如何在Haskell中对中间值进行模式匹配 [英] How to pattern-match an intermediate value in Haskell

查看:80
本文介绍了如何在Haskell中对中间值进行模式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Bartosz Milewski撰写的《程序员的类别理论》 一书中,第4.3章.

In the book Category Theory for Programmers by Bartosz Milewski, chapter 4.3.

您必须编写一个态射是部分函数的Kleisli类别.这是我无法编译的尝试:

You must code a Kleisli category where morphisms are partial functions. Here is my attempt which does not compile:

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进行模式匹配以测试是否为Valid(然后调用f)或是否为Invalid(然后返回Invalid).我该怎么办?

In the >=> operator definition, I want to pattern-match the intermediate value s to test if is Valid (and then call f) or if it is Invalid (and then return Invalid). How can I do this ?

推荐答案

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

You can use case to do pattern matching:

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

在您的问题中,您似乎还试图使用防护措施来进行模式匹配和绑定值. Haskell不允许这样做.保护只是一个布尔值表达式,对于前面的(有时是可选的)模式,它必须为true才能匹配. Haskell语言并没有真正将(==)运算符理解"为相等.它只是将其视为其他函数.实际上,可以为一个类型定义它,使其不与模式匹配所需的相同类型相等.

In your question you also seem to be trying to use guards for pattern matching and binding values. Haskell does not allow this. A guard is just a boolean valued expression which must be true for the preceding (sometimes optional) pattern to match. Haskell the language doesn’t really "understand" the (==) operator as meaning equality. It just sees it as a function like any other. And indeed one can define it for a type to not correspond to the same kind of equality that a pattern match requires.

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

A guard is allowed to use variables from the pattern (or from a larger scope) but can’t bind new ones like a pattern. Therefore this would be wrong because v would be undefined.

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

这也将使编译器基本上无法知道您的模式是否完整(即,没有任何情况下无法匹配的值)

It would also make it basically impossible for the compiler to ever know if your patterns are exhaustive (ie that there are no values which wouldn’t be matched by any case)

这篇关于如何在Haskell中对中间值进行模式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆