我正在學習 Haskell。
我正在嘗試查找與串列as元素相加的串列bs元素,將元素作為元組回傳:
findSum2 :: [Int] -> [Int] -> [(Int,Int,Int)]
findSum2 as bs = [(a, a', b) | a <- as, a' <- as, b <- bs, a a' == b]
該代碼有效。但是為了學習 Haskell,我試圖將其重寫為 do-notation:
findSum2 :: [Int] -> [Int] -> [(Int,Int,Int)]
findSum2 as bs = do
a <- as
a' <- as
b <- bs
if a a' == b then return (a, a', b) else return ()
然后打字員向我抱怨:
? Couldn't match type ‘()’ with ‘(Int, Int, Int)’
Expected type: [(Int, Int, Int)]
Actual type: [()]
平心而論,我知道會的。但是既然我不能跳過elseHaskell中的子句,我應該在else子句中的return陳述句中放什么?
謝謝。
uj5u.com熱心網友回復:
您不能回傳單位 ( ()),因為這意味著 thereturn (a, a', b)和 thereturn ()具有不同的型別:第一個是[(Int, Int, Int)],而后者是[()]。
你可以做的是使用一個空串列,以防守衛失敗,所以:
findSum2 :: [Int] -> [Int] -> [(Int,Int,Int)]
findSum2 as bs = do
a <- as
a' <- as
b <- bs
if a a' == b then return (a, a', b) else []
uj5u.com熱心網友回復:
您必須在else子句中回傳正確型別的內容。它可以是空串列[],也可以是抽象值之一,例如mzeroor empty。
或者您可以洗掉if運算式并使用該guard函式。
import Control.Monad (guard)
findSum2 :: [Int] -> [Int] -> [(Int,Int,Int)]
findSum2 as bs = do
a <- as
a' <- as
b <- bs
guard (a a' == b)
return (a, a', b)
通過此實作,您現在還可以將函式簽名概括為:
findSum2 :: MonadPlus m => m Int -> m Int -> m (Int, Int, Int)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/357898.html
