林试图找到一个列表,其中的元素都是由我自己创建的数据类型的最大元素,采用了倍,而不是递归地做这件事。但是我有一个错误落得“不能匹配类型”。由于IM相当新的Haskell有看到的问题麻烦IM和希望知道如何正确适用foldr相似的功能。
我在获得的最大元素的尝试看起来是这样的:
- (foldr相似的比较(头列表)(尾列表))
这将无法编译。
我已经包括了数据类型及其公式和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
折叠车名单后我预期的结果是获得了“大汽车”,基本上是指与最大的时间上车。但我最终得到一个编译错误,因为错误的类型。
问题是类型和comparison
的定义。
首先,类型应该是Car -> Car -> Car
:你拍二Car
值并返回更大的。
其次,你的comparison
的定义尝试一个参数匹配的元组,而不是两个独立的参数。删除括号和逗号。
comparison :: Car -> Car -> Car
comparison car1 car2 = if car1 > car2 then car1 else car2
(当然,comparison
只是max
限于Car
而非Ord a => a
。
comparison :: Car -> Car -> Car
comparison = max
而且,正如罗宾Zigmond指出,foldr comparison x
基本上是maximum
一个适当的值x
。)
考虑简化型foldr
的。
foldr :: (a -> b -> b) -> b -> [a] -> b
这是一个很大的通用比你需要,因为你所面对的所有汽车。这意味着找到与Car
最大foldr
,类型变为
foldr :: (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.