【问题标题】:Function currying in HaskellHaskell 中的函数柯里化
【发布时间】:2010-12-05 13:54:19
【问题描述】:

我有一个函数:

powerOf :: Int -> Int -> Int

示例操作系统用法:

*Main Data.List> powerOf 100 2
2
*Main Data.List> powerOf 100 5
2

我有两个问题。首先 - 为什么它不起作用:

map (powerOf 100) [2, 5]

我想得到 [2, 2]。

第二个问题。我试图创建 pariatl 函数。像这样的:

powerOfN :: Int -> Int
powerOfN num = powerOf num

这样使用它:

let powerOf100 = powerOfN 100
powerOf100 2
powerOf100 5

但我收到了错误消息:

simplifier.hs:31:15:
    Couldn't match expected type `Int'
           against inferred type `Int -> Int'
    In the expression: powerOf num
    In the definition of `powerOfN': powerOfN num = powerOf num

这里充满了可能的代码:

divided :: Int -> Int -> Bool
divided a b = 
  let x = fromIntegral a
      y = fromIntegral b
  in (a == truncate (x / y) * b)

listOfDividers :: Int -> [Int]
listOfDividers num =
               let n = fromIntegral num
                   maxN = truncate (sqrt n)
               in [n | n <- [1.. maxN], divided num n]


isItSimple :: Int -> Bool
isItSimple num = length(listOfDividers num) == 1

listOfSimpleDividers :: Int -> [Int]
listOfSimpleDividers num = [n | n <- listOfAllDividers, isItSimple n]
                     where listOfAllDividers = listOfDividers num

powerOfInner :: Int -> Int -> Int -> Int
powerOfInner num p power
             | divided num p = powerOfInner (quot num p) p (power + 1)
             | otherwise = power

powerOf :: Int -> Int -> Int
powerOf num p = powerOfInner num p 0


powerOfN :: Int -> Int
powerOfN num = powerOf num

powerOf 返回 num 中 p 的最大幂。例如:100 = 2 * 2 * 5 *5,所以 powerOf 100 2 = 2。10 = 2 * 5,所以 powerOf 10 2 = 1。

如何修复错误?谢谢。

【问题讨论】:

  • 你能提供powerOf的代码吗?
  • powerOf 似乎已损坏或命名错误。据我所知,100 的 2 次方是 10000。
  • 我发布我所有的代码并解释powerOf。
  • 它仍然可以正常工作 — ideone.com/2fOdW
  • 这是我的错误。我正在尝试 map (powerOf 100) [1, 2, 5] 并得到无限递归。 ideone.com/kuGVM

标签: haskell currying partial-application


【解决方案1】:

使用您的代码,除了 powerOfN 函数。我无法用map (powerOf 100) [2,5] 重现您的问题。

*Main> map (powerOf 100) [2,5]
[2,2]

你有什么错误吗?


关于你的第二个问题:

powerOfN :: Int -> Int
powerOfN num = powerOf num

类型签名不正确。

powerOfN 接受一个整数并返回一个函数,该函数接受一个整数并返回一个整数。

所以类型签名应该是

powerOfN :: Int -> (Int -> Int)

与(感谢delnan确认)相同:

powerOfN :: Int -> Int -> Int

【讨论】:

  • 甚至没必要,powerOfN 100powerOf 100一样。
  • @Piotr:没错,这就是隐式柯里化/使 n 元函数一元函数返回 (n-1) 元函数的全部意义。
  • 是的,比你。这是我的错误。我正在尝试 map (powerOf 100) [1, 2, 5] 并得到无限递归。
【解决方案2】:

我想我看到了你的困惑。您想要一个带有单个参数的“powerOf”版本,因此您尝试定义只带有一个参数的“powerOfN”。但实际上“powerOf”已经做到了。您必须将“->”作为类型运算符阅读。正如“+”是数字运算符一样,“->”是类型运算符;它需要两种类型并返回一种新类型。所以

Foo -> Bar

是从“Foo”到“Bar”的函数。但由于这是一种类型,您可以对其应用另一个“->”操作,如下所示:

Int -> (Int -> Int)

这意味着一个函数接受一个 Int,并返回一个新函数,该函数接受第二个 Int 并返回一个 Int 作为结果。

Haskell 将“->”运算符定义为右结合,所以这种情况下的括号可以去掉,所以看起来像这样:

Int -> Int -> Int

“powerOf”函数的类型是什么。所以你可以使用“powerOf”并给它一个参数,你得到的是一个需要第二个参数的新函数。这就是你想要的。

【讨论】:

    猜你喜欢
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    • 2016-01-01
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多