我试图找到列表的max元素,其中的元素是我自己创建的数据类型,使用fold而不是递归地进行操作。但是,我最终遇到错误“无法匹配类型”。作为Haskell的新手,我看不到问题并希望知道如何正确应用foldr函数。
我尝试获取最大元素的方法如下:
-(文件夹比较(头列表)(尾列表))
无法编译。
我包括了Eq和Ord的数据类型及其实例,还包括了比较功能。
-- Car data type
data Car = Car {registration :: String,
hour :: Integer,
minute :: Integer,
tupleForm :: PTime
}
-- Equality comparison between Car data types
-- reqiures equality by registration number, hours and minutes
instance Eq Car where
(Car r1 h1 m1 _) == (Car r2 h2 m2 _) = (r1 == r2) && (((h1*60)+m1) ==
((h2*60)+m2))
-- Order comparison between Car data types
-- Compares time of two Cars , hours and minutes
instance Ord Car where
compare (Car _ h1 m1 _) (Car _ h2 m2 _) = compare ((h1*60)+m1)
((h2*60)+m2)
-- Returns the larger Car
comparison :: (Car,Car) -> Car
comparison(car1,car2) = if(car1 > car2) then car1 else car2
折叠汽车列表后,我的预期结果是获得“最大汽车”,这基本上意味着时间最长的汽车。但是由于类型错误,我最终遇到了编译错误。
答案 0 :(得分:3)
问题是comparison
的类型和定义。
首先,类型应为Car -> Car -> Car
:您需要两个 Car
值并返回较大的值。
第二,您对comparison
的定义尝试将单个参数匹配为元组,而不是两个单独的参数。删除括号和逗号。
comparison :: Car -> Car -> Car
comparison car1 car2 = if car1 > car2 then car1 else car2
(当然,comparison
仅限于max
而非Car
的{{1}}。
Ord a => a
而且,正如罗宾·齐格蒙德(Robin Zigmond)所指出的,comparison :: Car -> Car -> Car
comparison = max
基本上是foldr comparison x
,具有适当的值maximum
。)
答案 1 :(得分:1)
考虑简化的foldr
类型。
foldr :: (a -> b -> b) -> b -> [a] -> b
这比您需要的要通用得多,因为您要处理所有汽车。这意味着要用Car
找到最大的foldr
,类型变为
foldr :: (Car -> Car -> Car) -> Car -> [Car] -> Car
第一个参数是在两个Car之间选择的函数。在您的情况下,您想要max
,因为它的类型
max :: Ord a => a -> a -> a
成为
max :: Car -> Car -> Car
并完全匹配。
foldr
的第二个参数被命名为z
,代表零。它是折叠过程的种子。为此,您也可以使用通过head
获得的列表的第一个元素。
类型[Car]
的列表参数显然是您要计算其最大值的列表。您可以传递整个列表,但是头部已经作为z
自变量。最好是tail list
。
给出以下列表(在修改Car
以删除tupleForm
并派生Show
实例之后)
cars = [ Car "A" 1 2, Car "B" 3 4, Car "C" 10 10 ]
用foldr
找到最大值是
λ> foldr max (head cars) (tail cars)
Car {registration = "C", hour = 10, minute = 10}
请注意,此foldr
的应用等效于maximum
,但您不必完全相信。添加
import Test.QuickCheck
在源文件顶部,然后
prop_max :: [Car] -> Property
prop_max l =
not (null l) ==>
maximum l == foldr max (head l) (tail l)
instance Arbitrary Car where
arbitrary = do
r <- oneof $ map return ["Apple","Orange","Banana"]
h <- choose (0,23)
m <- choose (0,59)
return (Car r h m)
使该断言更具信心。
λ> quickCheck prop_max
+++ OK, passed 100 tests.