简体   繁体   中英

And another one type error

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)]

Error message:

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.

As I understand the type of 'x' and 'y'. Is it right? Is it square require the Int. But what is the type 'x' and 'y'? I thinked they are Int.

Your type is too general. You are passing x and y to isItSquare , which is expecing Int s, but you don't know that x and y are Int s. They could be, but they could be any other instance of Integral as well. Either change the signature to the more specific:

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

Or have your helper functions work on more general types:

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

You've declared sumOfSquare , hipotenuse , squareCheck and isItSquare as operating on Int .

However, you've said that calc can use any type a , as long as a is Integral .

Either declare calc like this:

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

...or change all your other functions like this:

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

a has type a (the signature explicitly says so, that's what "is a rigid type variable bound by the type signature for calc " means), and x is taken from the list [1..a] , so it also has type a (and same for y ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM