function - 如何在一个函数中找到具有多个输入的最大函数输出?
问题描述
我想要一个函数 maxfunct,输入 f(一个函数)和输入 n(int),它计算函数 f 的所有输出,输入为 0 到 n,并检查输出的最大值。
我对haskell很陌生,我尝试过的是这样的:
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
想法是我将 f 的每个输出存储在一个列表中,并检查该列表中的最大值。我怎样才能做到这一点?
解决方案
你很近。首先,让我们注意我们正在尝试编写的函数的类型。从类型入手,除了可以帮助你更好地感受函数,还可以让编译器给我们更好的错误信息。看起来你期待一个函数和一个整数。函数的结果应该与maximum
(即应该满足Ord
)兼容,并且还需要有一个合理的“零”值(所以为了简单起见,我们只说它需要Num
;实际上,我们可能会考虑使用Bounded
orMonoid
或其他东西,取决于您的需要,但Num
现在就足够了)。
所以这就是我建议的类型签名。
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
从技术上讲,我们可以更概括一点,也可以使用Int
a 类型参数(需要Num
、Enum
和Ord
),但这可能有点矫枉过正。现在,让我们看看您的实现。
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
不错。第一种情况肯定是好的。但我认为您可能对列表理解语法有些困惑。我们想说0
的是:从to中取每一个值n
,应用f
到它上面,然后最大化。
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum [f x | x <- [0..n]]
你有它。对于它的价值,你也可以map
很容易地做到这一点。
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum $ map f [0..n]
这只是您发现更容易阅读的问题。我自己是map
/filter
人,但很多人更喜欢列表推导,所以每个人都有自己的。