这是我的代码:
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)
Run Code Online (Sandbox Code Playgroud)
我需要显示calc的结果.它不起作用:
*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
Run Code Online (Sandbox Code Playgroud)
调用测试工作正确:
*Main> test 1
Sides 1 2 3
Run Code Online (Sandbox Code Playgroud)
正如我所说,原因是calc函数返回SidesType和Haskell列表可以显示SidesType,但不能显示SidesType列表.
我是否需要更改SidesType描述?或者我是否需要以其他方式修复错误?
还有一个问题 - 我可以在不定义新数据类型的情况下显示calc函数的结果:
calc :: Int -> (Int, Int, Int)
calc a = [x y (hipotenuse x y) | x <- [1..a], y <-[1..a], (isItSquare x y)]
Run Code Online (Sandbox Code Playgroud)
?
显示结果的calc,你用做只是做了结果的test:
*Main> calc 4
[Sides 3 4 5,Sides 4 3 5]
Run Code Online (Sandbox Code Playgroud)
您试图显示值的calc,你不能做; 没有可以打印的函数的表示(这应该是有意义的 - show至少在默认情况下,应该显示可以read返回的内容,并且您不能使用函数执行此操作).如果Haskell可以显示某些内容,那么它可以显示一些内容; 某处有一个宣言
instance Show a => Show [a] where
...
Run Code Online (Sandbox Code Playgroud)
(也有类似的情况Read,Eq以及Ord:可读的东西名单本身就是可读,可为比较相等的东西列表可以自己平等相比,和东西可以责令本身可以有序列表)
是的,您可以使用元组而不是定义SidesType:
calc :: Int -> [(Int, Int, Int)]
calc a = [(x,y,hipotenuse x y) | x <- [1..a], y <- [1..a], isItSquare x y]
Run Code Online (Sandbox Code Playgroud)
你wrote-什么x y (hipotenuse x y)-tries调用函数x有两个参数y和hipotenuse x y.当然,x不是一个功能,所以这是行不通的.你需要逗号和括号.
此外,由于你似乎是Haskell的新手,这里有一些小的风格点:人们通常写truncate $ sqrt x或truncate (sqrt x)代替truncate(sqrt(x)),并且列表理解中的括号isItSquare x y和Sides x y (hypotenuse x y)(也可以写Sides x y $ hypotenuse x y)也是不必要的.我也可能会写,data Sides = Sides Int Int Int deriving (Eq,Show,Read)而不是data SidesType = Sides ...,但我真的可能会使用(Int,Int,Int),因为你表明你想要.而且我可能会通过替换Int一个实例来赋予函数更通用的类型Integral; 例如,calc :: Integral i => i -> [(i,i,i)].但这更多的是品味问题.