Haskell 实现`MyMonad Free f`
Typeclassopedia定义了Haskell 实现`MyMonad Free f`,haskell,Haskell,Typeclassopedia定义了自由monad数据类型 无数据f a=变量a |节点(f(自由f a)) 鉴于: class (MyMonad m) where ret :: a -> m a flatMap :: m a -> (a -> m b) -> m b 下面是我在实现这个typeclass的MyMonad实例方面的不完整尝试 instance Functor f => MyMonad (Free f) whe
自由monad
数据类型
无数据f a=变量a
|节点(f(自由f a))
鉴于:
class (MyMonad m) where
ret :: a -> m a
flatMap :: m a -> (a -> m b) -> m b
下面是我在实现这个typeclass的MyMonad
实例方面的不完整尝试
instance Functor f => MyMonad (Free f) where
ret = Var
flatMap (Var x) f = f x
flatMap (Node xs) f = error
请帮我解释一下>=
/binding在免费
单子上意味着什么
当我与
Applicative(Free f)
斗争时,我被鼓励尝试实现Monad
实例。在这种情况下,可以帮助我如何继续。它们给出了尚未实现的“洞”应该具有的类型的信息
在定义中使用键入的孔而不是错误
:
instance Functor f => MyMonad (Free f) where
ret = Var
flatMap (Var x) g = f x
flatMap (Node xs) g = _
给出如下错误消息(此处简化):
那个洞里的freeb
。。。它应该有哪个构造函数<代码>变量或节点
现在,Free a
类型的值就像一棵树,它的叶子上有a
类型的值(Var
构造函数),其分支节点由functorf
塑造
什么是免费的?把它想象成是把一棵树“嫁接”到每一片叶子上。这些新树是使用传递给>=
的函数从叶子中的值构造的
这有助于我们继续:现在我们知道flatMap(Node xs)f=.
模式右侧的构造函数必须是Node
,因为“嫁接”到树上的新事物不会将已经存在的节点折叠成树叶,它只会将树叶扩展成全新的树
仍在使用类型孔:
instance Functor f => MyMonad (Free f) where
ret = Var
flatMap (Var x) g = f x
flatMap (Node xs) g = Node _
Found hole `_' with type: f (Free f b)
...
Relevant bindings include
g :: a -> Free f b (bound at Main.hs:10:21)
xs :: f (Free f a) (bound at Main.hs:10:17)
在xs
中,我们有一个freea
封装在f
中,但是f
是一个函子,我们可以很容易地映射到它上面
但是如何将
freeffa
转换成孔所需的freefb
?直观地说,这个freeffa
将比>=
开始时的“更小”,因为我们已经去掉了一个“分支节点”。也许它甚至是一个叶节点,就像其他模式匹配覆盖的情况一样!这建议使用某种类型的递归。在这种情况下,可以帮助您继续。它们给出了尚未实现的“洞”应该具有的类型的信息
在定义中使用键入的孔而不是错误
:
instance Functor f => MyMonad (Free f) where
ret = Var
flatMap (Var x) g = f x
flatMap (Node xs) g = _
给出如下错误消息(此处简化):
那个洞里的freeb
。。。它应该有哪个构造函数<代码>变量或节点
现在,Free a
类型的值就像一棵树,它的叶子上有a
类型的值(Var
构造函数),其分支节点由functorf
塑造
什么是免费的?把它想象成是把一棵树“嫁接”到每一片叶子上。这些新树是使用传递给>=
的函数从叶子中的值构造的
这有助于我们继续:现在我们知道flatMap(Node xs)f=.
模式右侧的构造函数必须是Node
,因为“嫁接”到树上的新事物不会将已经存在的节点折叠成树叶,它只会将树叶扩展成全新的树
仍在使用类型孔:
instance Functor f => MyMonad (Free f) where
ret = Var
flatMap (Var x) g = f x
flatMap (Node xs) g = Node _
Found hole `_' with type: f (Free f b)
...
Relevant bindings include
g :: a -> Free f b (bound at Main.hs:10:21)
xs :: f (Free f a) (bound at Main.hs:10:17)
在xs
中,我们有一个freea
封装在f
中,但是f
是一个函子,我们可以很容易地映射到它上面
但是如何将
freeffa
转换成孔所需的freefb
?直观地说,这个freeffa
将比>=
开始时的“更小”,因为我们已经去掉了一个“分支节点”。也许它甚至是一个叶节点,就像其他模式匹配覆盖的情况一样!这建议使用某种递归。从实现Functor
实例开始。然后请注意,一般来说,monad可以被描述为一个支持return
和join::m(ma)->ma
的函子。您可以看到如何使用=实现join
吗?从实现Functor
实例开始。然后请注意,一般来说,monad可以被描述为一个支持return
和join::m(ma)->ma
的函子。您可以看到如何使用=
join :: Functor f => Free f (Free f a) -> Free f a
join (Var a) = a
join (Node m) = Node (fmap join m)