在阅读(和掠的某些部分)浦wadler的纸张单子,我决定工作,通过纸更加紧密,定义函和应用实例对每个单元是他介绍的。使用类型的同义词

type M a = State -> (a, State)
type State = Int

浦wadler使用定义的国家单,我有如下(使用相关的名称,所以我可以界定他们与新的宣言之后)。

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 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

为了结合s'圣'和实际上返回一个价值,例如,

fmap f m = S (\st -> let (a, s) = isntThisAnnoying st m in (f a, s))

是否有另一种方式来做到这一点,并不使用这些辅助职能?

有帮助吗?

解决方案

如果你看看 在这里,, 你会看到,他们定义是这样说的:

newtype State s a = State { runState :: (s -> (a,s)) }

这样可以给内lambda一个名称。

其他提示

通常的办法是定义 newtype newtype S a = S {runState : State -> (a, State)}.然后代替你的 isntThisAnnoying s (S m) 你可以写 runState t s 哪里 t 是一样的 S m.
你必须使用一个 newtype 因为类型的同义词,不能typeclass实例。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top