2016-06-08 2 views
0

Я пытаюсь написать функцию, которая проверяет, является ли квадратный корень числа целым или нет. Моя функция выглядит следующим образом:Haskell Нет экземпляра для ... возникающего

check :: [Int] -> [Int] 
check xs = filter (\n -> n == round sqrt n) xs 

И сообщения об ошибках, я получаю следующие:

No instance for (Integral (Int -> Int)) 
(maybe you haven't applied enough arguments to a function?) 
arising from a use of "round" 
In the second argument of "(==)", namely "round sqrt n" 
... 
No instance for (Floating a0) arising from a use of `sqrt' 
The type variable `a0' is ambiguous 
Note: there are several potential instances: 
instance Floating Double -- Defined in `GHC.Float' 
instance Floating Float -- Defined in `GHC.Float' 
In the first argument of `round', namely `sqrt' 

Edit: Я в конечном итоге переписывать весь вопрос, я надеюсь, что это еще не проблема!

+1

Вы хотите 'round (sqrt n)', а не 'round sqrt n'. Также вам нужно, чтобы из Integral в правом выражении. Итак, 'check = filter (\ n -> n == fromIntegral (round (sqrt n))) – pdexter

+0

Не вызывает ли функция право-ассоциативный? Кроме того, я все еще получаю два сообщения об ошибках: 'Нет экземпляра для (RealFrac Int), возникающего из-за использования« round »' 'Нет экземпляра для (Floating Int), возникающего из-за использования« sqrt »' – DQQpy

+0

Удалите ' [Int] -> [Int] ', вы хотите' [Double] -> [Double] 'например. Если вы действительно хотите «Int», вам нужно дополнительно изменить определение. Вызовы функций лево-ассоциативные. – pdexter

ответ

1

Так что я нашел другое решение по себе:

check :: [Int] -> [Int] 
check xs = filter (\n -> (ceiling (sqrt (fromIntegral n))) == (floor (sqrt (fromIntegral n)))) xs 

Это единственный, который не бросает ошибку компиляции (в моем случае).

2

он будет работать, если вы удалите левый fromIntegral:

test n = n == fromIntegral (round n) 

причина заключается в том, что, как это ваш n должен быть RealFrac (round) и Integral (fromIntegral), но нет типа в прелюдии который является одновременно (ни Integer, ни Double, например)

если убрать левую fromIntegral вам нужно только n иметь тип, который является экземпляром RealFrac - Double, например

правая сторона выглядит так:

RealFrac -round-> Integral -fromIntegral-> RealFrac 

, если у вас есть сомнения, вы всегда можете спросить GHCI:

Prelude> :i RealFrac 
class (Real a, Fractional a) => RealFrac a where 
    properFraction :: Integral b => a -> (b, a) 
    truncate :: Integral b => a -> b 
    round :: Integral b => a -> b 
    ceiling :: Integral b => a -> b 
    floor :: Integral b => a -> b 
    -- Defined in ‘GHC.Real’ 
instance RealFrac Float -- Defined in ‘GHC.Float’ 
instance RealFrac Double -- Defined in ‘GHC.Float’ 

, как вы можете видеть этот тип класс дает вам cut -back номера Integral (спросите Integral, чтобы узнать, что это значит - намек: думает, что что-то вроде Целые)

вы также увидите известных экземпляров

если вы видите RealFrac Int это означает, что он искал, чтобы найти RealFrac экземпляр определения Int (его нет)

Почему есть Int другое дело:

  • либо вы запускали в формальность: GHCi по умолчанию n до Int здесь - вы, вероятно, столкнулись с ужасным monomorphism restriction - что не должно происходить так с новыми версиями GHC, но хорошо ...
  • или использовать его в контексте, какие ограничения, чтобы это Int (который мы не видим)

быть честным, я не уверен, что здесь

+0

Это не сработало без первого изIntegral. Редактировать: Но означает ли это, что отIntegral это что-то вроде ограничения для следующего? Я думал, что это что-то вроде функции конвертера. – DQQpy

+0

Также Да, его Int из-за контекста;) – DQQpy

+0

, очевидно, что это бесполезно с 'Int' в первую очередь (' Int' всегда * целое *) - но в этом случае это будет что-то вроде 'test n = n == round (fromIntegral n)' - вы используете 'fromIntegral' для доступа к некоторому' 'RealFrac''у, а затем можете использовать' round' для возврата, но помните: это практически бесполезно – Carsten

2

Это должно быть

check :: [Int] -> [Int] 
check xs = filter (\n -> fromIntegral n == round (sqrt (fromIntegral n))) xs 

сообщение об ошибке говорит вам проблему:

(maybe you haven't applied enough arguments to a function?) 
arising from a use of "round" 

Потому что round sqrt n звонки round с аргументами sqrt и n.

Но это все еще не делает то, что вы хотите. Вы должны sqrt другой стороны, а

check :: [Int] -> [Int] 
check xs = filter (\n -> sqrt (fromIntegral n) == round (sqrt (fromIntegral n))) xs 
+0

О, конечно, другая сторона тоже ... Ну, я определенно слишком устал прямо сейчас, поэтому я попробую это завтра, спасибо вам большое! – DQQpy

+0

еще ошибки: 'Неоднозначность типа переменный "a0" в ограничениях: (Floating а0) , возникающий при использовании "SQRT" (Интеграл a0) , вытекающем из использования "fromIntegral" (Num a0) возникающего от использования «fromIntegral» ' У вас, ребята, есть ссылка или что-то еще, где я могу узнать все эти вещи о числовых классах? Я не мог найти ничего новичка дружелюбным и информативным с Google. – DQQpy

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