如何在Haskell中模式匹配中间值 问题:
在Bartosz Milewski的《程序员范畴理论》一书中,第4.3章 必须编写一个Kleisli类别,其中态射是部分函数。以下是我未编译的尝试:如何在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 -
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是用于模式匹配的,但它似乎只用于对值执行测试。