[英]How to write a recursive function in Haskell that takes two lists as arguments and returns two list when a condition is met
我正在嘗試編寫一個 function,它需要兩個列表(list1 和 list2),以字符串形式表示為 arguments,然后遞歸迭代 list1 並比較 list2 中的值。 當 list1 和 list2 的值相等時,遞歸應該中斷並返回兩個列表(已修改)。
例如。 list1 = "abcdef"。 列表 2 =“定義”
偽代碼:
在上述情況下,這將返回:“def”“ef”
到目前為止我得到了什么:
isEqual :: String -> String -> String ->String
isEqual (s : os) (p : ps)
| p /= s = isEqual os (p : ps)
| otherwise = s:os ps
但是,我從 vs-code 收到以下錯誤消息:
• 無法將預期類型“String -> String”與實際類型“[Char]”匹配可能的原因:“(:)”應用於太多 arguments
在表達式中: s: os ps 在 'isEqual' 的等式中: isEqual (s: os) (p: ps) | p /= s = isEqual os (p: ps) | 否則 = s: os pstypecheck(-Wdeferred-type-errors)
無法將預期類型 '[Char] -> [Char]' 與實際類型 '[Char]' 匹配 function 'os' 應用於一個參數,但其類型 '[Char]' 沒有
在'(:)'的第二個參數中,即'os ps'
在表達式中: s: os pstypecheck(-Wdeferred-type-errors)
您的類型簽名將不起作用。 類型簽名:
isEqual :: String -> String -> String -> String
描述了一個 function,它接受三個輸入字符串並產生一個 output 字符串。 為了接受兩個輸入字符串並生成兩個 output 字符串,您需要編寫如下內容:
isEqual :: String -> String -> (String, String)
此 function 將返回兩個字符串的對或“元組”。 這是返回兩個值的標准方法,如果不將它們配對,您將找不到返回兩個字符串的合理方法。
在此更改之后,您需要做的就是調整您的otherwise
情況以返回一對(s:os, ps)
:
isEqual :: String -> String -> (String, String)
isEqual (s : os) (p : ps)
| p /= s = isEqual os (p : ps)
| otherwise = (s:os, ps)
此功能似乎可以執行您想要的操作:
λ> isEqual "abcdef" "def"
("def","ef")
當需要在更大的程序中使用此 function 調用的結果時,您可以使用函數fst
和snd
從返回的對中提取兩個列表,也可以使用模式匹配來命名這兩個列表。 例如:
main = do
let (lst1, lst2) = isEqual "abcdef" "def"
putStrLn $ "First list was " ++ show lst1
putStrLn $ "Second list was " ++ show lst2
根據您的后續評論,如果您想將isEqual
返回的兩個列表傳遞給 function ,后者將這兩個列表作為單獨的 arguments,通常的方法是通過您發現的let
語句:
let (lst1, lst2) = isEqual (s:os) ps in isMatch ls1 lst2
您的第一次嘗試也可以,但您需要一些額外的括號才能正確解析:
isMatch (fst (isEqual (s:os) ps)) (snd (isEqual (s:os) ps))
甚至結合這兩種方法:
let lsts = isEqual (s:os) ps in isMatch (fst lsts) (snd lsts)
還有其他幾種方法。 高階 function uncurry
“轉換”為一個需要一對的 function,因此您可以編寫:
(uncurry isMatch) (isEqual (s:os) ps)
^^^^^^^^^^^^^^^^^
`-- this function takes the pair directly
或者,去掉多余的括號:
uncurry isMatch (isEqual (s:os) ps)
同樣,這些只是一些選擇。 我認為您使用let
找到的解決方案是最清晰的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.