在阅读Wadler关于monad的论文(并略读了部分内容)之后,我决定更仔细地研读论文,为他描述的每个monad定义函子和应用实例。使用类型同义词函数/ Haskell中状态的应用实例
type M a = State -> (a, State)
type State = Int
Wadler用来定义状态单子,我有以下的(使用相关的名字,所以我可以用NEWTYPE声明以后定义它们)。
fmap' :: (a -> b) -> M a -> M b
fmap' f m = \st -> let (a, s) = m st in (f a, s)
pure' :: a -> M a
pure' a = \st -> (a, st)
(<@>) :: M (a -> b) -> M a -> M b
sf <@> sv = \st -> let (f, st1) = sf st
(a, st2) = sv st1
in (f a, st2)
return' :: a -> M a
return' a = pure' a
bind :: M a -> (a -> M b) -> M b
m `bind` f = \st -> let (a, st1) = m st
(b, st2) = f a st1
in (b, st2)
。当切换到在NEWTYPE声明使用类型构造,例如,
newtype S a = S (State -> (a, State))
一切散开。一切都只是稍作修改,例如,
instance Functor S where
fmap f (S m) = S (\st -> let (a, s) = m st in (f a, s))
instance Applicative S where
pure a = S (\st -> (a, st))
但是没有在GHC由于事实lambda表达式是隐藏该类型的构造函数中运行。现在我看到的唯一的解决办法是定义一个函数:
isntThisAnnoying s (S m) = m s
为了送绑定到“ST”,实际上返回一个值,例如,
fmap f m = S (\st -> let (a, s) = isntThisAnnoying st m in (f a, s))
是否有另一种方式做到这一点那不使用这些辅助功能?
这也意味着'runState = flip isntThisAnnoying'。 – kennytm 2010-08-20 18:48:26
好的 - 所以虽然还需要一个辅助功能,但我可以使用记录来定义类型,免费获取该功能。那么你所说的是,没有办法避免使用像'runState'或'run'这样的函数。谢谢。 – danportin 2010-08-20 21:40:33
如果它伤害你想它作为一个函数,而不是想它作为一个结构字段访问器。 :-) – 2010-08-21 00:50:37