问题
Question
In the book Category Theory for Programmers by Bartosz Milewski, chapter 4.3.
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
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 ?
回答1:
You can use case
to do pattern matching:
f >=> g = \x ->
case f x of
Valid v -> g v
Invalid -> Invalid
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.
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)
来源:https://stackoverflow.com/questions/59226842/how-to-pattern-match-an-intermediate-value-in-haskell