Haskell 如何使应用程序实例成为特定的数据类型
我正在读格雷厄姆·赫顿写的关于哈斯克尔的书,不知道如何进行练习的一部分。练习内容如下: 给定以下类型表达式Haskell 如何使应用程序实例成为特定的数据类型,haskell,monads,applicative,Haskell,Monads,Applicative,我正在读格雷厄姆·赫顿写的关于哈斯克尔的书,不知道如何进行练习的一部分。练习内容如下: 给定以下类型表达式 data Expr a = Var a | Val Int | Add (Expr a) (Expr a) deriving Show 包含某种类型a的变量,演示如何将这种类型转换为Functor、Applicative和Monad类的实例。借助示例,解释此类型的>=运算符的作用 我在定义Applicative的运算符时遇到问题。的类型为: (<*>) :: Expr
data Expr a = Var a | Val Int | Add (Expr a) (Expr a) deriving Show
包含某种类型a的变量,演示如何将这种类型转换为Functor、Applicative和Monad类的实例。借助示例,解释此类型的>=
运算符的作用
我在定义Applicative的
运算符时遇到问题。
的类型为:
(<*>) :: Expr (a -> b) -> Expr a -> Expr b
最后,我对monad中的>>=表示怀疑。这个操作符的思想是做一些事情,比如替换变量?比如:
expr >>= (\x -> if x == 'a' then Val 6 else Var x) >>= (\x -> if x == 'b' then Val 7 else Var x)
当您定义了
pure
和(>>=)
时,()
的一个可能定义是
(<*>) = Control.Monad.ap
事实上,
()
的任何定义必须与存在Monad
实例的定义相同。如您所正确注意的,在以下情况下:
(Val n) <*> mx = ???
fmap g (Val n) = ???
(Add l r) <*> mx
您需要生成一个表达式b
。你还记得这个案例吗:
(Val n) <*> mx = ???
fmap g (Val n) = ???
(Add l r) <*> mx
当你有:
g :: a -> b
Val n :: Expr a
您需要生成一个表达式b
?你在那里找到了解决办法
就本案而言:
(Val n) <*> mx = ???
fmap g (Val n) = ???
(Add l r) <*> mx
您需要生成一个表达式b
。如果你有一些函数可以使用l
和mx
并创建一个Expr b
。如果存在这样一个函数,它可能会有签名:
someFunc :: Expr (a -> b) -> Expr a -> Expr b
当然,对于
someFunc l mx
和someFunc r mx
,这两种类型都是Expr b
,如果只使用一种,那将是一种耻辱。如果有某种方法可以从两个Expr b
部分构造Expr b
,那将真的是蜜蜂的膝盖。您在Val n
案例中稍微错误地说明了可用的类型。您没有Expr a
,而是Expr(a->b)
,根本没有a
或b
(甚至也没有a->b
中的函数,因为Val
只包含Int
)。事实上,这种情况很简单,因为您周围没有有用的值:唯一合理的方法是使用构造函数Val
生成输出,因为您无法凭空生成b
。Val
的类型可以专门化为Val::Int->Expr b
,幸运的是,您有一个Int
,因此您可以编写:
(Val n) <*> mx = Val n
(Val n)mx=Val n
在(Val n)mx
中,n
的类型是什么?(注意
的类型)数据表达式a=Var a | Val Int |。。。很抱歉我误读了我以为是Var。。。