我正在尝试编写一个接受函数和两个输入的函数,并返回最大化函数的参数。这是我想要使用的设置:
max :: Eq a => (a -> Int) -> a -> a -> a
例如,该函数应该如下工作:
maximize (+3) 5 10 = 10
因为(3 + 5)< (3 + 10)
我想我需要做这样的事情:
maximize :: Eq a => (a -> Int) -> a -> a -> a
maximize f x y = max (f x) (f y)
这种方法似乎并没有起作用。谢谢你的帮助!
答案 0 :(得分:7)
您的问题是max (f x) (f y)
提供了f x
或f y
,而不是x
或y
。你必须比较前一对值然后返回后者之一。一种方法是使用compare
,然后对其结果进行模式匹配,如下所示:
-- You don't actually need the `Eq a` constraint here.
maximize :: (a -> Int) -> a -> a -> a
maximize f x y = case compare (f x) (f y) of
-- etc. (I will let you fill in the details.)
使用Data.Ord
中的comparing
撰写的一种快捷方式,可让您将compare (f x) (f y)
替换为comparing f x y
。上面由user2407038建议的另一个快捷方式是使用Data.List
中的maximumBy
将其全部缩减为单行maximumBy (comparing f) [x,y]
。
答案 1 :(得分:5)
直接实施怎么样:
maximize f x y = if (f x) > (f y) then x else y
答案 2 :(得分:1)
另一种选择是
maximize f x y = argmax f [x,y]
但这需要安装list-extras package。
但是,我认为其他答案更惯用(@duplode)和更简单(@Uri Goren)。
答案 3 :(得分:0)
使用警卫的一种不同但非常简单的方法:
maxiM :: (Ord b) => (a -> b) -> a -> a -> a
maxiM func v1 v2
| (func v1) < (func v2) = (func v2)
| otherwise = (func v1)
我建议看看learnyouahaskell。