jus*_*.me 2 haskell functional-programming tuples pattern-matching
我知道我可以使用模式匹配功能参数,如下所示:
fn :: (Integral a) => (a,a) -> (a, a)
fn (x,y) = (y,x)
Run Code Online (Sandbox Code Playgroud)
但是如何匹配返回值?我希望这样的事情:
g :: (Integral a) => a -> a
g z = do
(x, y) = fn (z, z + 5)
x `mod` y
Run Code Online (Sandbox Code Playgroud)
这会导致语法错误.有没有办法匹配返回值?基本上,我想将返回的元组拆分为两个变量.
在do使用语法糖的单子.但是你的功能不是monad.
你可以做的是使用let-clause,如:
g :: (Integral a) => a -> a
g z = let (x,y) = fn (z,(z+5)) in x `mod` yRun Code Online (Sandbox Code Playgroud)
或where-clause:
g :: (Integral a) => a -> a
g z = x `mod` y
where (x,y) = fn (z,(z+5))Run Code Online (Sandbox Code Playgroud)
您还可以在lambda表达式中定义模式,如:
g :: (Integral a) => a -> a
g z = (\(x,y) -> x `mod` y) $ fn (z,(z+5))Run Code Online (Sandbox Code Playgroud)
沿着这些方向,您还可以定义一个辅助函数来执行模式匹配,例如:
g :: (Integral a) => a -> a
g z = h $ fn (z,(z+5))
where h (x,y) = x `mod` yRun Code Online (Sandbox Code Playgroud)
如果有需要进行不同的处理(如几种模式这可能是有用的Nothing,并Just x为Maybe a类型).
比如说你定义了一个函数:
foo :: Int -> Int -> Maybe Int
foo x y | x > y = Just x
| otherwise = Nothing
Run Code Online (Sandbox Code Playgroud)
你可以bar用一个辅助函数定义qux来处理输出foo,比如:
bar :: Int -> Int -> Int
bar x y = qux $ foo x y
where qux Nothing = y
qux (Just z) = z
Run Code Online (Sandbox Code Playgroud)
最后在2元组的情况下,您可以决定不使用模式匹配,但是使用fst :: (a,b) -> a和snd :: (a,b) -> b,例如:
g :: (Integral a) => a -> a
g z = let t = fn (z,(z+5)) in ( fst t) `mod` (snd t)Run Code Online (Sandbox Code Playgroud)
但这不太优雅,因为这里必须开始思考什么fst和snd做什么,如果不进行优化,它可能会导致额外的计算开销.
选择哪一个当然取决于背景和个人品味.由于这里的模式是唯一的,我会选择let或where模式,但像法国人所说:" Lesgoûtsetles couleurs ne se discutent pas. ".