Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何使应用程序实例成为特定的数据类型_Haskell_Monads_Applicative - Fatal编程技术网

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