1)这是我的代码,find函数需要将(节点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.
我显然还在学习这个,所以对解决方案的解释也会受到赞赏,谢谢你!
答案 0 :(得分:5)
语法
Node a => ...
意味着Node
是类型类,但事实上,它只是一种普通的数据类型。
因此这个签名就足够了
find :: Node a -> a -> Bool
示例:
find (Node val left right) = ...
find Empty = ...
答案 1 :(得分:3)
...
find :: (Node a) => Node a -> a -> Bool
'(节点a)=>' bit说 a 可以是任何东西,只要它实现 Node 类型类。您的代码没有定义任何名为 Node 的类型类,因此最快的方法是删除该约束:
...
find :: Node a -> a -> Bool
find n s
但是,由于您使用 s 所做的事情,您将收到更多错误:
....
| s == "asd" = True
你的类型签名说 s 可以是任何东西,但是你试图用“asd”测试它是否相等,这意味着 s 必须是一个字符串。将类型签名更改为以下内容将允许您的代码进行编译,但可能无法完成您想要的任务。
find :: Node a -> String -> Bool
...
看起来您的目标是以递归方式扫描 Node 结构测试是否与某些已知值相等,直到找到所需内容。以下是该函数应该看起来的前两行。
find :: (Eq a) => Node a -> a -> Bool
find (Node n _ _) s | n == s = True
...
“(Eq a)=>”表示 a 必须是为其定义的 == , / = 等。
第二行演示了如何“访问节点中的特定变量”的问题。您使用Haskell的一个名为“模式匹配”的功能来构建一个参数应该是什么样子的模板。然后,编译器将实际参数与您提供的模板相匹配。
答案 2 :(得分:0)
在dario的帮助下,这里提供的是我的最终解决方案
find :: (Eq a) => Node a -> a -> Bool
find (Node val left right) s
| s == val = True
| s /= val = False