簡體   English   中英

Haskell:如何定義函數可以作為參數的類型? 以及如何訪問數據結構中的未命名變量?

[英]Haskell: How do I define the types my function can take as parameters? AND how do I access unnamed variables in a data structure?

1)這是我的代碼,find函數需要使用一個(Node a)和一個類型(a)作為參數,但是我的函數定義似乎不起作用,我在做什么錯? 我可以在網上找到很少的信息,非常感謝您的幫助!

2)實現find函數后,我需要訪問Node中的特定變量,該怎么辦?!

-- int for comparisons
find :: (Node a) => Node a -> a -> Bool
find n s
| s == "asd" = True
| s /= "asd" = False

data Node a = Node a (Node a) (Node a)
| Empty

myTree = Node "parent" (Node "left" Empty Empty)
(Node "right" Empty Empty)

這是我收到的錯誤消息:

Type constructor `Node' used as a class
In the type `(Node a) => Node a -> a -> Bool'
In the type signature for `find':
find :: (Node a) => Node a -> a -> Bool
Failed, modules loaded: none.

我顯然仍在學習此方法,因此請您對解決方案進行解釋,謝謝!

語法

Node a => ...

這意味着Node是一個類型類,但實際上,它只是一個普通的數據類型。

因此,這個簽名就足夠了

find :: Node a -> a -> Bool

例:

find (Node val left right) = ...
find Empty = ...

問題1

...
find :: (Node a) => Node a -> a -> Bool

'((Node a)=>')位表示,只要實現了Node類型類, a可以是任何東西。 您的代碼沒有定義任何稱為Node的類型類,因此克服此錯誤的最快方法就是刪除該約束:

...
find :: Node a -> a -> Bool
find n s

但是,由於使用s ,您將獲得更多錯誤:

....
| s == "asd" = True

您的類型簽名說s可以是任何東西,但是您嘗試使用“ asd”測試它是否相等,這意味着s必須是String 將您的類型簽名更改為以下內容將允許您的代碼進行編譯,但可能無法實現您想要的功能。

find :: Node a -> String -> Bool
...

問題2

看來您的目標是遞歸地掃描Node結構測試以找到具有已知值的相等性,直到找到所需的值。 這是該函數可能看起來像的前兩行。

find :: (Eq a) => Node a -> a -> Bool
find (Node n _ _) s | n == s = True
...

“(Eq a)=>”表示a必須是為其定義了==/ =等的東西。

第二行演示了有關如何“訪問節點中的特定變量”的問題的答案。 您可以使用Haskell的一種稱為“模式匹配”的功能來構建一個參數應為什么樣的模板。 然后,編譯器使實際參數適合您提供的模板。

在達里奧的幫助下,這里是我最終的解決方案

find :: (Eq a) => Node a -> a -> Bool
find (Node val left right) s
    | s == val      = True
    | s /= val      = False

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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