我正在關注這篇關于 catamorphism 的文章,我正在嘗試為這樣的遞回資料型別定義折疊函式
type Node anyType
= Leaf Id (Maybe anyType)
| Tree Id (List (Node anyType))
我寫的是這樣的:
foldTree fLeaf fTree acc node =
let
recurse =
foldTree fLeaf fTree
in
case node of
Leaf id v ->
let
newAcc = fLeaf acc (id, v)
in
newAcc
Tree id l ->
let
newAcc = fTree acc id
in
l |> List.foldl recurse newAcc
如果我不推斷foldTree函式編譯的型別,但它似乎不可用:
collectIds node =
let
fLeaf acc (id,v) = id :: acc
fTree acc id = id :: acc
in
foldTree fLeaf fTree [] node
拋出以下內容:
TYPE MISMATCH - The 1st argument to `foldTree` is not what I expect:
173| foldTree fLeaf fTree [] node
#^^^^^#
This `fLeaf` value is a:
#List a# -> ( a, b ) -> #List a#
But `foldTree` needs the 1st argument to be:
#Node anyType# -> ( Id, Maybe anyType ) -> #Node anyType#
自動推斷其型別foldTree使其不可編譯并拋出以下內容:
-- Auto Inferred
foldTree : (c -> (Id, Maybe anyType) -> a) -> (c -> Id -> b) -> c -> Node anyType -> d
TYPE MISMATCH - Something is off with the 1st branch of this `case` expression:
126| newAcc
#^^^^^^#
This `newAcc` value is a:
#a#
But the type annotation on `foldTree` says it should be:
#d#
#Hint#: Your type annotation uses `a` and `d` as separate type variables. Your
code seems to be saying they are the same though. Maybe they should be the same
in your type annotation? Maybe your code uses them in a weird way?
如果我嘗試按照提示進行操作,仍然無法編譯
foldTree : (c -> (Id, Maybe anyType) -> a) -> (c -> Id -> b) -> c -> Node anyType -> a
TYPE MISMATCH - This function cannot handle the argument sent through the (|>) pipe:
134| l |> List.foldl recurse newAcc
#^^^^^^^^^^^^^^^^^^^^^^^^^#
The argument is:
List #(Node anyType)#
But (|>) is piping it to a function that expects:
List #c#
#Hint#: Your type annotation uses type variable `c` which means ANY type of value
can flow through, but your code is saying it specifically wants a `Node` value.
Maybe change your type annotation to be more specific? Maybe change the code to
be more general?
Read <https://elm-lang.org/0.19.1/type-annotations> for more advice!Elm
TYPE MISMATCH - The 1st argument to `foldl` is not what I expect:
134| l |> List.foldl recurse newAcc
#^^^^^^^#
This `recurse` value is a:
c -> Node anyType -> #a#
But `foldl` needs the 1st argument to be:
c -> Node anyType -> #Node anyType#
#Hint#: Your type annotation uses type variable `a` which means ANY type of value
can flow through, but your code is saying it specifically wants a `Node` value.
Maybe change your type annotation to be more specific? Maybe change the code to
be more general?
我被困住了。準確地遵循文章上的型別似乎也不起作用。我知道文章中的代碼是 F#,我正在研究 Elm,但我認為在這種情況下,它應該是 100% 可翻譯的。
我哪里錯了?
提前致謝!
uj5u.com熱心網友回復:
您已將論點翻轉為List.foldl. fold 函式首先獲取值,然后是累加器,而您的recurse函式首先獲取累加器,然后是值。
對此的簡單解決方法是擴展遞回函式并在將其傳遞給時翻轉引數foldTree:
recurse v a = foldTree fLeaf fTree a v
此外,有趣的是,注釋的型別recurse將使其編譯,但顯然會產生錯誤的結果。我沒有進一步了解原因,因為它是錯誤的,但是您應該從中吸取的教訓是始終注釋您的頂級功能。這將為您提供更好的錯誤訊息,但也可以防止您的代碼意外編譯但產生錯誤的結果。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/426869.html
上一篇:遞回解決方案中的錯誤退出條件
