【发布时间】:2021-05-28 06:52:01
【问题描述】:
我正在处理 Haskell 中的一个函数,该函数接收一个包含矩形宽度和高度的字符串(该字符串的格式类似于“宽度长度”或“1 3”)。然后它递归地计算出填充该矩形的正方形的边长,并返回填充矩形的每个正方形的所有边长(它只会返回每个正方形的一个边长,因为正方形只有一个唯一的边长)。
我遇到的问题是,每当我运行下面的代码时,Haskell 都会告诉我,当预期类型 [Int] 时,我试图返回类型 [[Int]]。我对 Haskell 很陌生,并且在将 Int 放入集合并返回之前,努力弄清楚究竟是什么导致我的 Int 变成了 [Int]。
module MakeSquares where
import Data.List
solve :: String -> [Int]
solve s
|lengthOne == lengthTwo = return [lengthOne]
--If we run into any problems then add a where statement definining the equation in "show"
|lengthOne > lengthTwo = do f <- solve (intercalate " " [show lengthOneMinusTwo, show lengthTwo])
return (lengthTwo:f)
|lengthOne < lengthTwo = do f <- solve (intercalate " " [show lengthTwoMinusOne, show lengthOne])
return (lengthOne:f)
where
input = words s
stringLengthOne = input!!0
stringLengthTwo = input!!1
lengthOne = read stringLengthOne::Int
lengthTwo = read stringLengthTwo::Int
lengthOneMinusTwo = lengthOne - lengthTwo
lengthTwoMinusOne = lengthTwo - lengthOne
Haskell 在尝试运行时向我发送的错误如下。
MakeSquares.hs:8:28: error:
* Couldn't match type `[Int]' with `Int'
Expected type: [Int]
Actual type: [[Int]]
* In the expression: return [lengthOne]
In an equation for `solve':
solve s
| lengthOne == lengthTwo = return [lengthOne]
| lengthOne > lengthTwo
= do f <- solve (intercalate " " [show lengthOneMinusTwo, ....])
return (lengthTwo : f)
| lengthOne < lengthTwo
= do f <- solve (intercalate " " [show lengthTwoMinusOne, ....])
return (lengthOne : f)
where
input = words s
stringLengthOne = input !! 0
stringLengthTwo = input !! 1
lengthOne = read stringLengthOne :: Int
....
|
8 | |lengthOne == lengthTwo = return [lengthOne]
| ^^^^^^^^^^^^^^^^^^
MakeSquares.hs:11:30: error:
* Couldn't match type `[Int]' with `Int'
Expected type: [Int]
Actual type: [[Int]]
* In a stmt of a 'do' block: return (lengthTwo : f)
In the expression:
do f <- solve
(intercalate " " [show lengthOneMinusTwo, show lengthTwo])
return (lengthTwo : f)
In an equation for `solve':
solve s
| lengthOne == lengthTwo = return [lengthOne]
| lengthOne > lengthTwo
= do f <- solve (intercalate " " [show lengthOneMinusTwo, ....])
return (lengthTwo : f)
| lengthOne < lengthTwo
= do f <- solve (intercalate " " [show lengthTwoMinusOne, ....])
return (lengthOne : f)
where
input = words s
stringLengthOne = input !! 0
stringLengthTwo = input !! 1
lengthOne = read stringLengthOne :: Int
....
|
11 | return (lengthTwo:f)
| ^^^^^^^^^^^^^^^^^^^^
MakeSquares.hs:11:48: error:
* Couldn't match expected type `[Int]' with actual type `Int'
* In the second argument of `(:)', namely `f'
In the first argument of `return', namely `(lengthTwo : f)'
In a stmt of a 'do' block: return (lengthTwo : f)
|
11 | return (lengthTwo:f)
| ^
MakeSquares.hs:13:30: error:
* Couldn't match type `[Int]' with `Int'
Expected type: [Int]
Actual type: [[Int]]
* In a stmt of a 'do' block: return (lengthOne : f)
In the expression:
do f <- solve
(intercalate " " [show lengthTwoMinusOne, show lengthOne])
return (lengthOne : f)
In an equation for `solve':
solve s
| lengthOne == lengthTwo = return [lengthOne]
| lengthOne > lengthTwo
= do f <- solve (intercalate " " [show lengthOneMinusTwo, ....])
return (lengthTwo : f)
| lengthOne < lengthTwo
= do f <- solve (intercalate " " [show lengthTwoMinusOne, ....])
return (lengthOne : f)
where
input = words s
stringLengthOne = input !! 0
stringLengthTwo = input !! 1
lengthOne = read stringLengthOne :: Int
....
|
13 | return (lengthOne:f)
| ^^^^^^^^^^^^^^^^^^^^
MakeSquares.hs:13:48: error:
* Couldn't match expected type `[Int]' with actual type `Int'
* In the second argument of `(:)', namely `f'
In the first argument of `return', namely `(lengthOne : f)'
In a stmt of a 'do' block: return (lengthOne : f)
|
13 | return (lengthOne:f)
| ^
我一直在尝试调试这个程序的方式是按照我认为程序会在 ghci 中发送命令的顺序手动发送命令。不幸的是,我还没有找到导致我输入错误的原因。
【问题讨论】:
-
你真的不应该使用
!!或字符串作为输入。在 haskell 中,您应该使用数据类型来表示复杂的数据结构