Jor*_*rdi 3 monads haskell applicative
我正在阅读有关Haskell的Graham Hutton的书,并且不要一口气地进行练习。练习内容如下:
给定以下类型表达式
data Expr a = Var a | Val Int | Add (Expr a) (Expr a) deriving Show
Run Code Online (Sandbox Code Playgroud)
包含某些类型a的变量,展示了如何使这种类型成为Functor,Applicative和Monad类的实例。借助示例,说明>>=该类型的运算符的作用。
我在定义<*>Applicative运算符时遇到了问题。的类型<*>是:
(<*>) :: Expr (a -> b) -> Expr a -> Expr b
Run Code Online (Sandbox Code Playgroud)
我不知道该怎么用(Val n) <*> mx,因为从理论上讲我需要提供一个Expr b,但是我所拥有的只是一个,Expr a并且没有转换(a -> b)的函数。
我也不知道该怎么办(Add l r) <*> mx。
这是我的实现。
instance Functor Expr where
--fmap :: (a -> b) -> Expr a -> Expr b
fmap g (Var x) = Var (g x)
fmap g (Val n) = Val n
fmap g (Add l r) = Add (fmap g l) (fmap g r)
instance Applicative Expr where
--pure :: a -> Expr a
pure = Var
-- <*> :: Expr (a -> b) -> Expr a -> Expr b
(Var g) <*> mx = fmap g mx
--(Val n) <*> mx = ???
--(Add l r) <*> mx = ???
instance Monad Expr where
-- (>>=) :: Expr a -> (a -> Expr b) -> Expr b
(Var x) >>= g = g x
(Val n) >>= g = Val n
(Add l r) >>= g = Add (l >>= g) (r >>= g)
expr = Add (Add (Var 'a') (Val 4)) (Var 'b')
Run Code Online (Sandbox Code Playgroud)
最后,我对monad中的>> =有疑问。这个运算符的想法是做诸如替换变量之类的事情?喜欢:
expr >>= (\x -> if x == 'a' then Val 6 else Var x) >>= (\x -> if x == 'b' then Val 7 else Var x)
Run Code Online (Sandbox Code Playgroud)
如您所正确指出的,在这种情况下:
(Val n) <*> mx = ???
Run Code Online (Sandbox Code Playgroud)
你有:
Val n :: Expr (a -> b)
mx :: Expr a
Run Code Online (Sandbox Code Playgroud)
并且您需要产生一个Expr b。您是否记得这种情况:
fmap g (Val n) = ???
Run Code Online (Sandbox Code Playgroud)
当你有:
g :: a -> b
Val n :: Expr a
Run Code Online (Sandbox Code Playgroud)
而您需要产生一个Expr b?您在那里找到了解决方案。
对于这种情况:
(Add l r) <*> mx
Run Code Online (Sandbox Code Playgroud)
你有:
l :: Expr (a -> b)
r :: Expr (a -> b)
mx :: Expr a
Run Code Online (Sandbox Code Playgroud)
并且您需要产生一个Expr b。如果只有你有一些功能,可以采取l和mx创造的Expr b。这样的功能(如果存在)可能具有签名:
someFunc :: Expr (a -> b) -> Expr a -> Expr b
Run Code Online (Sandbox Code Playgroud)
当然,如果同时使用someFunc l mx和和someFunc r mx,都使用type Expr b,那只能使用一个是可耻的。如果有一些方法构建一个Expr b由两个Expr b部分,即真的会蜜蜂的膝盖。