Haskell 中状态的函子/应用实例

发布于 2024-09-15 03:38:34 字数 1389 浏览 7 评论 0原文

在阅读(并浏览了 Wadler 关于 monad 的论文的某些部分)后,我决定更仔细地研究这篇论文,为他描述的每个 monad 定义函子和应用实例。 类型同义词

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

使用Wadler 用来定义状态 monad 的

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 声明中使用类型构造函数时,

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

但是由于 lambda 表达式隐藏在该类型构造函数中,GHC 中什么也没有运行。现在我看到的唯一解决方案是定义一个函数:

isntThisAnnoying s (S m) = m s

为了将 s 绑定到“st”并实际返回一个值,例如,

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

是否有另一种不使用这些辅助函数的方法来做到这一点?

After reading (and skimming some sections of) Wadler's paper on monads, I decided to work through the paper more closely, defining functor and applicative instances for each of the monads he describes. Using the type synonym

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

Wadler uses to define the state monad, I have the following (using related names so I can define them with a newtype declaration later on).

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)

When I switch to using a type constructor in a newtype declaration, e.g.,

newtype S a = S (State -> (a, State))

everything falls apart. Everything is just a slight modification, for instance,

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

however nothing runs in GHC due to the fact that the lambda expression is hidden inside that type constructor. Now the only solution I see is to define a function:

isntThisAnnoying s (S m) = m s

in order to bind s to 'st' and actually return a value, e.g.,

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

Is there another way to do this that doesn't use these auxiliary functions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野の 2024-09-22 03:38:34

如果您查看此处,您会看到他们是这样定义的:

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

以便给内部 lambda 命名。

If you look here, you will see that they define it this way:

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

so as to give the inner lambda a name.

女皇必胜 2024-09-22 03:38:34

通常的方法是定义 newtype newtype S a = S {runState : State -> (a,状态)}。然后,您可以编写 runState t s 而不是 isntThisAnnoying s (S m),其中 tS m 相同>.
您必须使用 newtype 因为类型同义词不能是类型类实例。

The usual way is to define newtype newtype S a = S {runState : State -> (a, State)}. Then instead of your isntThisAnnoying s (S m) you can write runState t s where t is the same as S m.
You have to use a newtype because type synonyms cannot be typeclass instances.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文