Próbuję zdefiniować nowy typ o nazwie „Poly” wHaskell, gdzie typ jest listą „Num”, która reprezentuje wyrażenie wielomianowe. [1,2,3] odpowiada 3x ^ 2 + 2x + 1, a zatem [4,5,6,0,0 ... 0] jest tym samym wielomianem co [4,5,6].
Stworzyłem funkcję pomocnika o nazwie „chop”, aby usunąć 0 z końca listy, ale mam problem z porównaniem dwóch list. Jakieś pomysły, dlaczego moje użycie „instancji” tutaj nie działa?
Kompiluje się, ale gdy próbujesz porównać 2 wystąpienia Poly, WinGHCi zawiesza się.
newtype Poly a = P [a]
x :: Num a => Poly a
chop :: (Eq a, Num a) => Poly a -> Poly a
chop (P l) = if (last l) == 0 then chop (P $ init l) else P l
instance (Num a, Eq a) => Eq (Poly a) where
(==) m n = if (chop m) == (chop n) then True else False
Odpowiedzi:
8 dla odpowiedzi № 1Problem polega na tym, że zdefiniowałeś (==)
być rekurencyjnym. Trochę upraszczając definicję, masz:
m == n = chop m == chop n
To ocenia tak:
m == n
-> { definition of (==) }
chop m == chop n
-> { definition of (==) }
chop (chop m) == chop (chop n)
-> { definition of (==) }
chop (chop (chop m)) == chop (chop (chop n))
-> { ... }
Zamiast odsyłać test równości z powrotem do testu równości dla wielomianów, powinieneś wysłać do równości dla list. Na przykład można pisać
m == n = let P m" = chop m; P n" = chop n in m" == n"
zamiast.