Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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 - Fatal编程技术网

如何在Haskell中模式匹配中间值 问题:

如何在Haskell中模式匹配中间值 问题:,haskell,Haskell,在Bartosz Milewski的《程序员范畴理论》一书中,第4.3章 必须编写一个Kleisli类别,其中态射是部分函数。以下是我未编译的尝试: data Optional a = Valid a | Invalid deriving (Show) return :: a -> Optional a return x = Valid x (>=>) :: (a -> Optional b) -> (b -> Optional c) -> (a -

在Bartosz Milewski的《程序员范畴理论》一书中,第4.3章

必须编写一个Kleisli类别,其中态射是部分函数。以下是我未编译的尝试:

data Optional a = Valid a | Invalid deriving (Show)

return :: a -> Optional a
return x = Valid x

(>=>) :: (a -> Optional b) -> (b -> Optional c) -> (a -> Optional c)
f (>=>) g = \x ->
    let s = f x
    in | s == Valid v = g v
       | s == Invalid = Invalid

=>
运算符定义中,我想对中间值
s
进行模式匹配,以测试
是否有效(然后调用
f
),或者它是否无效(然后返回
无效)。如何执行此操作?

您可以使用
case
进行模式匹配:

f >=> g = \x ->
  case f x of
    Valid v -> g v
    Invalid -> Invalid
在您的问题中,您似乎还试图为模式匹配和绑定值使用保护。哈斯克尔不允许这样。guard只是一个布尔值表达式,必须为true才能与前面的(有时是可选的)模式匹配。Haskell语言并不真正“理解”操作符
(==)
的意思是相等。它只是把它看作一个函数,就像其他函数一样。事实上,我们可以为一个类型定义它,使其不符合模式匹配所需的相同类型的相等性

守卫可以使用模式(或更大范围)中的变量,但不能像模式那样绑定新变量。因此,这将是错误的,因为
v
将是未定义的

f >=> g = \x ->
  case f x of
    _ | x == Valid v -> g v
    _ | x == Invalid -> Invalid

这也使得编译器根本不可能知道您的模式是否详尽无遗(即没有任何情况下都无法匹配的值)

我认为首先,你应该让Conditor将可选类型作为Monad类型类的一个实例,然后Kleisli合成操作符将免费提供
f>=>g=\x->f x>>=g
。我将在稍后的Redu中尝试,这本书的重点是逐步学习如何应用范畴理论。从某种意义上说,
case
是Haskell中的基本解构工具,其他模式将desugar匹配到核心语言中的
case
语句中。所以得到一个句柄是很好的。好吧,在特殊情况下,保护是一种语法糖,在这种情况下,保护被应用于函数的参数,对吗?@vkubicki,我不明白你的意思。你认为警卫是什么?你认为它是做什么用的?有一个叫做guardsI的部分,我认为guards是用于模式匹配的,但它似乎只用于对值执行测试。