簡體   English   中英

如何在 Haskell 中編寫遞歸 function 將兩個列表作為 arguments 並在滿足條件時返回兩個列表

[英]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 =“定義”

偽代碼:

  • 對於 list1 中的字符
  • 如果 char==list2[0] --> [char:] list2[1:]

在上述情況下,這將返回:“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 調用的結果時,您可以使用函數fstsnd從返回的對中提取兩個列表,也可以使用模式匹配來命名這兩個列表。 例如:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM