2015-11-08 3 views
0

У меня есть функция для поиска простых чисел, а затем я хочу написать функцию, которая принимает число и возвращает первое большее простое число. Вот мой подход:Haskell - не может получить следующее наибольшее простое (не соответствует типу)

isPrime :: (Integral a) => a -> Bool 
isPrime x = and $ foldl (\acc y -> (x `mod` y /= 0):acc) [] [2..round . sqrt . fromIntegral $ (x-1)] 

primes = filter isPrime [2..] 

getNextPrime :: (Integral a) => a -> a 
getNextPrime n = head (dropWhile (<n) primes) 

Но когда я пытаюсь импортировать его в GHCI, я получаю эту ошибку:

[1 of 1] Compiling Main    (a.hs, interpreted) 

a.hs:35:39: 
    Couldn't match type ‘a’ with ‘Integer’ 
     ‘a’ is a rigid type variable bound by 
      the type signature for getNextPrime :: Integral a => a -> a 
      at a.hs:34:17 
    Expected type: [a] 
     Actual type: [Integer] 
    Relevant bindings include 
     n :: a (bound at a.hs:35:14) 
     getNextPrime :: a -> a (bound at a.hs:35:1) 
    In the second argument of ‘dropWhile’, namely ‘primes’ 
    In the first argument of ‘head’, namely ‘(dropWhile (< n) primes)’ 
Failed, modules loaded: none. 

, но когда я пытаюсь просто вставив:

head (dropWhile (<30) primes) 

возвращается 31, как и ожидалось, и его тип Integral.

Я попытался редактировать типы функций или явно указывать, например. n :: Integer, но это не помогло. Я уверен, что это будет какая-то тривиальность.

Благодаря

+0

Вам нужно добавить подпись типа для 'primes'. Это будет '' primes :: Integral a => [a] '' –

ответ

0

Как Саймон отметил, что вам нужна сигнатура типа на primes. Следующий код

primes :: (Integral a) => [a] 
primes = filter isPrime [2..] 

компилируется. GHC пытается сделать типы без явной полиморфной сигнатуры (т. Е. (Integral a) => ...) в сигнатуру с мономорфным типом. В вашем случае GHC решил «мономорфозировать» [2..] до [Integer]. Это называется «dreadedmonomorphismrestriction», для которого имеется множество сообщений, запущенных SOers. Итак, еще один способ сделать компиляцию кода - добавить язык pragma -XNoMonomorphismRestriction, хотя я настоятельно не рекомендую это для кого-то, кто изучает Haskell. Добавление подписей типов - это путь сюда.

Смежные вопросы