如何正确适用foldr相似功能

问题描述 投票:1回答:2

林试图找到一个列表,其中的元素都是由我自己创建的数据类型的最大元素,采用了倍,而不是递归地做这件事。但是我有一个错误落得“不能匹配类型”。由于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

折叠车名单后我预期的结果是获得了“大汽车”,基本上是指与最大的时间上车。但我最终得到一个编译错误,因为错误的类型。

haskell syntax fold
2个回答
3
投票

问题是类型和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。)


1
投票

考虑简化型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.
© www.soinside.com 2019 - 2024. All rights reserved.