Haskell用户定义的数据类型

时间:2014-10-14 20:27:48

标签: haskell types haskell-platform

我想将R数据的种类定义为有理数,其中R是(分母,分子),我定义为:

data R = R {n::Int,
            d::Int} deriving Show

现在我尝试做一个给出两个参数(一个R和一个R的列表)的函数,并返回一个等价为R的列表。我试试这个,但给我一个类型的错误。

equivalentes' :: [R] -> R -> [R]
equivalentes' [] _ = []
equivalentes' (x:xs) r
    | (n x `mod` n r == 0) && (d x `mod` d r == 0) = (R(d n)x): equivalentes' xs r
    | otherwise = equivalentes' xs r

我的想法是返回这样的内容:

> equivalentes'[R(2,4),R(3,5),R(4,8)] (R(1,2))
                   [R (2,4),R (4,8)]

2 个答案:

答案 0 :(得分:5)

问题在于表达式

R (d n) x : equivalentes' xs r

特别是

d n

n函数的类型为R -> Intd函数也是如此,但您已将n作为参数传递给d。也许你的意思是

R (d x) x

但由于x的类型为R,因此也不起作用,所以你可能意味着

R (d x) (n x)

或类似的东西。


另一方面,您不能R (1, 2),因为(1, 2)是两个Int的元组,而不仅仅是两个单独的Int。如果你真的想使用元组,你可以改为R 1 2uncurry R (1, 2)

答案 1 :(得分:3)

在Haskell中,函数和构造函数都是通过并置来应用的。例如,f x是应用于参数f的函数xf x y是应用于f的函数x,其结果应用于y。您可以将f x y视为f应用于两个参数xy。您不需要括号用于函数或构造函数应用程序,例如f (x y)表示不同的东西 - 在这种情况下x正在应用于y,而f (x, y)表示函数f已应用于元组(x, y)

对于您的代码,您需要使用

  • R 2 4代替R(2,4)
  • R (n x) (d x)代替R(d n)x

当我们对这些语法进行更改时,equivalentes将被写为

equivalentes :: [R] -> R -> [R]
equivalentes [] _ = []
equivalentes (x:xs) r
    | (n x `mod` n r == 0) && (d x `mod` d r == 0) = R (n x) (d x): equivalentes xs r
    | otherwise = equivalentes xs r

您的示例将被写为

equivalentes [R 2 4,R 3 5,R 4 8] (R 1 2)