在Haskell中添加实例声明错误

时间:2014-04-03 12:11:11

标签: haskell

我是Haskell的新手。这是我做的代码:

transition_world world = case world of
   (Head,(x,y)):cs-> (Tail,(x,y)): transition_world cs
   (Tail,(x,y)):cs -> (Conductor, (x,y)): transition_world cs
   (Empty, (x,y)):cs -> (Empty, (x,y)): transition_world cs 
   (Conductor, (x,y)):cs
     | element_occurrence Head == 1 || element_occurrence Head == 2
                  -> (Head, (x,y)): transition_world cs
     | otherwise  -> (Conductor, (x,y)): transition_world cs
   [] -> []

在尝试编译时,GHCi给了我这个错误:

Sources\Transitions\For_List_2D.hs:23:33:
No instance for (Eq (List_2D Cell -> Data.Integer_Subtypes.Nat))
  arising from a use of `=='
Possible fix:
  add an instance declaration for
  (Eq (List_2D Cell -> Data.Integer_Subtypes.Nat))
In the first argument of `(||)', namely
  `element_occurrence Head == 1'
In the expression:
  element_occurrence Head == 1 || element_occurrence Head == 2
In a stmt of a pattern guard for
               a case alternative:
  element_occurrence Head == 1 || element_occurrence Head == 2

Sources\Transitions\For_List_2D.hs:23:36:
No instance for (Num (List_2D Cell -> Data.Integer_Subtypes.Nat))
  arising from the literal `1'
Possible fix:
  add an instance declaration for
  (Num (List_2D Cell -> Data.Integer_Subtypes.Nat))
In the second argument of `(==)', namely `1'
In the first argument of `(||)', namely
  `element_occurrence Head == 1'
In the expression:
  element_occurrence Head == 1 || element_occurrence Head == 2

无法理解它对我有什么要求......我在哪里弄错了?我该如何解决?

额外1:

element_occurrence :: Eq e => e -> List_2D e -> Nat
element_occurrence element list = case list of
    (local_element, _): cs
       | local_element == element -> 1 + element_occurrence element cs
       | otherwise                ->     element_occurrence element cs
    [] -> 0

额外2:

local_elements :: Coord -> List_2D e -> List_2D e
local_elements (x, y) list = read_neighbours (x, y) 1 list
  where
    read_neighbours :: Coord -> Distance -> List_2D e -> List_2D e
    read_neighbours (x, y) dist list = case list of
        (element, (x_e, y_e)): cs
            |    abs (x_e - x) <= dist
            && abs (y_e - y) <= dist -> (element, (x_e, y_e)): read_neighbours (x, y) dist cs
            | otherwise              ->                        read_neighbours (x, y) dist cs
        [] -> []

local_elements_list :: Coord -> List_2D e -> [e]
local_elements_list (x, y) list = read_neighbours_list (x, y) 1 list
  where
    read_neighbours_list :: Coord -> Distance -> List_2D e -> [e]
    read_neighbours_list (x, y) dist list = case list of
        (element, (x_e, y_e)): cs
            |  abs (x_e - x) <= dist
            && abs (y_e - y) <= dist -> element: read_neighbours_list (x, y) dist cs
            |  otherwise             ->          read_neighbours_list (x, y) dist cs
        [] -> []

size :: List_2D e -> Nat
size list = case list of
   []    -> 0
   _: xs -> 1 + size xs

2 个答案:

答案 0 :(得分:3)

“为......添加实例声明”是GHC最具误导性的错误消息之一。一般来说,你应该忽略这个建议。

如果它想要一个实例的类型中有一个->,这基本上表明你正试图用一个只有结果才能实现的功能,即你已经忘记将函数应用于它的所有参数。显然,element_occurence的类型类似于Item -> List_2D Cell -> Nat,但您的代码中只有element_occurrence Head,这是部分应用的函数,它仍然具有类型{ {1}}。通过将其应用于List_2D Cell -> Nat,您将获得List_2D Cell,然后您可以将其与数字文字进行比较。

答案 1 :(得分:1)

您已将element_occurence定义为2个参数的函数:

element_occurrence :: Eq e => e -> List_2D e -> Nat
element_occurrence element list = -- more stuff

您只使用一个参数调用了element_occurence:

transition_world world = case world of
{- other cases -}
(Conductor, (x,y)):cs
  | element_occurrence Head == 1 || element_occurrence Head == 2 -> -- stuff

但是,这会为您提供类型&#34; List_2D Cell - &gt;的值。 Nat&#34;,一个函数类型,你试图测试对#34; 1&#34;和&#34; 2&#34;。

您需要做的是为element_occurence提供两个参数。

GHC在这里过于谦虚,并假设你真的意味着只用一个参数调用。 (==)类型为&#34; Eq a =&gt; a - &gt; a - &gt; Bool&#34;,所以如果你提供了一个实例&#34; Eq(List_2D Cell - &gt; Nat)&#34;,那么对(==)的调用就没问题了,但它无法找到该实例。因此,它会打印出第一条错误消息。

GHC数据显示,您很棒因此您可以立即修复该错误 ,并假设它已修复。但现在它看到&#34; 1&#34;和&#34; 2&#34;在一个预期&#34; List_2D单元格的地方 - &gt; Nat&#34;,(==)的另一面。现在,数字文字被重载以具有类型&#34; Num a =&gt; a&#34;,以便可以成为&#34; List_2D单元格 - &gt;纳特&#34;如果您提供实例&#34; Num(List_2D Cell - &gt; Nat)&#34;。它无法找到该实例,因此会吐出第二条错误消息。