2010-12-02 8 views
1
sumOfSquare :: Int -> Int -> Int 
sumOfSquare a b = a * a + b * b 

hipotenuse :: Int -> Int -> Int 
hipotenuse a b = truncate(sqrt(x)) 
      where x = fromIntegral(sumOfSquare a b) 

squareCheck :: Int -> Bool 
squareCheck n = truncate(sqrt(x)) * truncate(sqrt(x)) == n 
     where x = fromIntegral n 

isItSquare :: Int -> Int -> Bool 
isItSquare a b = squareCheck (sumOfSquare a b) 

calc :: (Integral a) => a -> [(a, a, a)] 
calc a = [(x, y, (hipotenuse x y)) | x <- [1..a], y <-[1..a], (isItSquare x y)] 

Message d'erreur autre:Et une erreur de type

Prelude> :load "some.hs" 
[1 of 1] Compiling Main    (some.hs, interpreted) 

some.hs:16:74: 
    Couldn't match expected type `Int' against inferred type `a' 
     `a' is a rigid type variable bound by 
      the type signature for `calc' at some.hs:15:18 
    In the first argument of `isItSquare', namely `x' 
    In the expression: (isItSquare x y) 
    In a stmt of a list comprehension: (isItSquare x y) 
Failed, modules loaded: none. 

Si je comprends bien le type de 'x' et 'y'. Est ce bien? Est-ce carré besoin de l'Int. Mais quel est le type 'x' et 'y'? Je pensais qu'ils sont Int.

+0

Quelle ligne est la ligne 16? – luqui

+0

fyi: hypoténuse :) – rampion

Répondre

4

Votre type est trop général. Vous passez x et y à isItSquare, qui expire Int s, mais vous ne savez pas que x et y sont Int s. Ils pourraient être, mais ils pourraient être n'importe quelle autre instance de Integral ainsi. Modifiez la signature au plus spécifique:

calc :: Int -> [(Int, Int, Int)] 

Ou ont vos fonctions d'aide travailler sur les types plus généraux:

squareCheck :: (Integral a) => a -> Bool 
... 
3

Vous avez déclaré sumOfSquare, hipotenuse, squareCheck et isItSquare comme opérant sur Int.

Cependant, vous avez dit que calc peut utiliser tout type a, aussi longtemps que a est Integral.

proclamera calc comme ceci:

calc :: Int -> [(Int, Int, Int)] 

... ou changer toutes vos autres fonctions comme celle-ci:

sumOfSquare :: (Integral a) => a -> a -> a 
2
calc :: (Integral a) => a -> [(a, a, a)] 
calc a = [(x, y, (hipotenuse x y)) | x <- [1..a], y <-[1..a], (isItSquare x y)] 

a est de type a (la signature dit explicitement, c'est ce que "est une variable de type rigide liée par la signature de type pour calc" signifie), et x est tiré de la liste [1..a], donc il a également le type a (et même pour y).