开发者

how to display a list

Here is my code:

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)

data SidesType = Sides Int Int Int deriving (Show)

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

test :: Int -> SidesType
test a = (Sides 1 2 3)

I need to display result of calc. It doesn't work:

*Main> calc
<interactive>:1:0:
    No instance for (Show (Int -> [SidesType]))
      arising from a use of `print' at <interactive>:1:0-3
    Possible fix:
      add an instance declaration for (Show (Int -> [SidesType]))
    In a stmt of an interactive GHCi command: print it

Call of test works correcly:

*Main> test 1
Sides 1 2 3

As I understanded the reason is the calc function return the list of SidesT开发者_Go百科ype and Haskell can display a SidesType, but cannot display the list of SidesType.

Do I need to change my SidesType description? Or do I need to fix error somehow else?

And another one question - can I display the result of calc function without defining new datatype:

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

?


Displaying the result of calc is done just as you did with the result of test:

*Main> calc 4
[Sides 3 4 5,Sides 4 3 5]

You tried to display the value of calc, which you can't do; there's no representation of a function which can be printed (which should make sense—show is, at least by default, supposed to display something which can be read back in, and you can't do that with functions). If Haskell can display something, then it can display a list of something; there's a declaration somewhere of

instance Show a => Show [a] where
  ...

(And there are similar instances for Read, Eq, and Ord: lists of readable things are themselves readable, lists of things which can be compared for equality can themselves be compared for equality, and lists of things which can be ordered can themselves be ordered.)

And yes, you can use a tuple instead of defining SidesType:

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

What you wrote—x y (hipotenuse x y)—tries to call the function x with the two arguments y and hipotenuse x y. Of course, x isn't a function, so this can't work. You need the commas and parentheses instead.


Also, since you seem to be new to Haskell, here are a few small style points: people typically write truncate $ sqrt x or truncate (sqrt x) instead of truncate(sqrt(x)), and the parentheses around isItSquare x y and Sides x y (hypotenuse x y) (which one could also write Sides x y $ hypotenuse x y) in the list comprehension are unnecessary. I'd also probably write data Sides = Sides Int Int Int deriving (Eq,Show,Read) instead of data SidesType = Sides ..., but I'd really probably use (Int,Int,Int) instead, as you indicate you want to. And I'd probably give the functions a more generic type by replacing Int with an instance of Integral; for instance, calc :: Integral i => i -> [(i,i,i)]. But this is more of a matter of taste.


As I understanded the reason is the calc function return the list of SidesType and Haskell can display a SidesType, but cannot display the list of SidesType.

nope. It CAN display a list. But it can not display a function Int->[SidesType]. So just supply an argument to calc.

*Main> calc 100
[Sides 3 4 5,Sides 4 3 5,Sides 5 12 13,Sides 6 8 10,Sides 7 24 25,Sides 8 6 10,Sides 8 15 17,Sides 9 12 15,Sides 9 40 41,Sides 10 24 26,Sides 11 60 61,Sides 12 5 13,Sides 12 9 15,Sides 12 16 20,Sides 12 35 37,Sides 13 84 85,Sides 14 48 50,Sides 15 8 17,Sides 15 20 25,Sides 15 36 39,Sides 16 12 20,Sides 16 30 34,Sides 16 63 65,Sides 18 24 30,Sides 18 80 82,Sides 20 15 25,Sides 20 21 29,Sides 20 48 52,Sides 20 99 101,Sides 21 20 29,Sides 21 28 35,Sides 21 72 75,Sides 24 7 25,Sides 24 10 26,Sides 24 18 30,Sides 24 32 40,Sides 24 45 51,Sides 24 70 74,Sides 25 60 65,Sides 27 36 45,Sides 28 21 35,Sides 28 45 53,Sides 28 96 100,Sides 30 16 34,Sides 30 40 50,Sides 30 72 78,Sides 32 24 40,Sides 32 60 68,Sides 33 44 55,Sides 33 56 65,Sides 35 12 37,Sides 35 84 91,Sides 36 15 39,Sides 36 27 45,Sides 36 48 60,Sides 36 77 85,Sides 39 52 65,Sides 39 80 89,Sides 40 9 41,Sides 40 30 50,Sides 40 42 58,Sides 40 75 85,Sides 40 96 104,Sides 42 40 58,Sides 42 56 70,Sides 44 33 55,Sides 45 24 51,Sides 45 28 53,Sides 45 60 75,Sides 48 14 50,Sides 48 20 52,Sides 48 36 60,Sides 48 55 73,Sides 48 64 80,Sides 48 90 102,Sides 51 68 85,Sides 52 39 65,Sides 54 72 90,Sides 55 48 73,Sides 56 33 65,Sides 56 42 70,Sides 56 90 106,Sides 57 76 95,Sides 60 11 61,Sides 60 25 65,Sides 60 32 68,Sides 60 45 75,Sides 60 63 87,Sides 60 80 100,Sides 60 91 109,Sides 63 16 65,Sides 63 60 87,Sides 63 84 105,Sides 64 48 80,Sides 65 72 97,Sides 66 88 110,Sides 68 51 85,Sides 69 92 115,Sides 70 24 74,Sides 72 21 75,Sides 72 30 78,Sides 72 54 90,Sides 72 65 97,Sides 72 96 120,Sides 75 40 85,Sides 75 100 125,Sides 76 57 95,Sides 77 36 85,Sides 80 18 82,Sides 80 39 89,Sides 80 60 100,Sides 80 84 116,Sides 84 13 85,Sides 84 35 91,Sides 84 63 105,Sides 84 80 116,Sides 88 66 110,Sides 90 48 102,Sides 90 56 106,Sides 91 60 109,Sides 92 69 115,Sides 96 28 100,Sides 96 40 104,Sides 96 72 120,Sides 99 20 101,Sides 100 75 125]


Haskell can display a list of SidesType just fine, it just can't display functions. calc is a function. If you want to display the result of calc, you'll have to call calc with an argument (of type Int).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜