我知道我可以对这样的函数参数使用模式匹配:
fn :: (Integral a) => (a,a) -> (a, a)
fn (x,y) = (y,x)
但是我怎样才能匹配返回值呢?我希望是这样的:
g :: (Integral a) => a -> a
g z = do
(x, y) = fn (z, z + 5)
x `mod` y
这会导致语法错误。有没有办法匹配返回值?基本上,我想将返回的元组拆分为两个变量。
最佳答案
do
被用作monads 的语法糖。但是,您的函数不是 monad。
您可以做的是使用 let
-clause,例如:
g :: (Integral a) => a -> a
g z = <b>let (x,y) = fn (z,(z+5)) in</b> x `mod` y
或者一个where
-clause:
g :: (Integral a) => a -> a
g z = x `mod` y
<b>where (x,y) = fn (z,(z+5))</b>
您还可以在 lambda-expression 中定义 模式,例如:
g :: (Integral a) => a -> a
g z = (\<b>(x,y)</b> -> x `mod` y) $ fn (z,(z+5))
按照这些思路,您还可以定义一个辅助函数来进行模式匹配,例如:
g :: (Integral a) => a -> a
g z = <b>h</b> $ fn (z,(z+5))
where <b>h</b> (x,y) = x `mod` y
如果有多个模式需要以不同方式处理(例如 Nothing
和 Just x
用于 Maybe a
类型)。
比如说你定义了一个函数:
foo :: Int -> Int -> Maybe Int
foo x y | x > y = Just x
| otherwise = Nothing
你可以用辅助函数qux
定义bar
来处理foo
的输出,比如:
bar :: Int -> Int -> Int
bar x y = qux $ foo x y
where qux Nothing = y
qux (Just z) = z
最后在2元组的情况下,你可以决定不使用模式匹配,而是使用fst::(a,b) -> a
和snd::(a,b) -> b
,比如:
g :: (Integral a) => a -> a
g z = let <b>t</b> = fn (z,(z+5)) in (<b> fst t</b>) `mod` (<b>snd t</b>)
但这不太优雅,因为这里必须开始考虑 fst
和 snd
做什么,而且如果没有优化,它可能会导致额外的计算开销。
选择哪一个当然取决于上下文和个人品味。由于这里的模式是唯一的,我会选择 let
或 where
模式,但就像法国人说的:“Les goûts et les couleurs ne se discutent过去了。”。
关于haskell - 返回值的模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43412324/