Функция карри в Хаскеле - PullRequest
       13

Функция карри в Хаскеле

0 голосов
/ 05 декабря 2010

У меня есть функция:

powerOf :: Int -> Int -> Int

пример использования os:

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

У меня два вопроса. Первое - почему это не работает:

map (powerOf 100) [2, 5]

Я хочу получить [2, 2].

И второй вопрос. Я пытаюсь создать париатальную функцию. Примерно так:

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 возвращает максимальную мощность p в num. Например: 100 = 2 * 2 * 5 * 5, поэтому powerOf 100 2 = 2. 10 = 2 * 5, поэтому powerOf 10 2 = 1.

Как исправить ошибки? Спасибо.

Ответы [ 2 ]

5 голосов
/ 05 декабря 2010

Использование вашего кода, кроме функции 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
0 голосов
/ 05 декабря 2010

Мне кажется, я вижу твое замешательство. Вам нужна версия «powerOf», которая принимает один аргумент, поэтому вы попытались определить «powerOfN», который принимает только один аргумент. Но на самом деле "powerOf" уже делает это. Вы должны прочитать «->» как оператор типа. Так же, как «+» является оператором для чисел, «->» является оператором для типов; он принимает два типа и возвращает новый. Так

Foo -> Bar

- это функция от "Foo" до "Bar". Но так как это тип, вы можете применить к нему другую операцию «->», например:

Int -> (Int -> Int)

, что означает функцию, которая принимает Int и возвращает новую функцию, которая берет вторую Int и возвращает Int в качестве результата.

Haskell определяет оператор "->" как ассоциативный справа, поэтому скобки в этом случае можно убрать, поэтому это выглядит так:

Int -> Int -> Int

Какой тип вашей функции "powerOf". Таким образом, вы можете использовать «powerOf» и дать ему один аргумент, и вы получите новую функцию, которая ожидает второй аргумент. Что ты и хотел.

...