我需要你的帮助。 我试图在haskell学习并做一个简单的任务,但对我来说仍然很难。 我想要做的是:读取用空格分隔的一行数字,迭代该列表,检查值,如果值不为零,则加1,否则为-1。我试着看一些教程和其他项目代码,但它只输出一堆错误。 我的代码:
import System.Environment
import Control.Monad
import Text.Printf
import Data.List
import System.IO
solve :: IO ()
solve = do
nums <- map read . words <$> getLine
print (calculate nums)
calculate (x:xs) = x + check xs
check num
| num == 0 =
-1
| otherwise =
1
main :: IO ()
main = do
n <- readLn
if n /= 0
then do
printf "Case: "
solve
else main
错误:
C:\Users\Donatas\Documents\haskell\la3.hs:9:21: error:
* Ambiguous type variable `b0' arising from a use of `read'
prevents the constraint `(Read b0)' from being solved.
Probable fix: use a type annotation to specify what `b0' should be.
These potential instances exist:
instance Read BufferMode -- Defined in `GHC.IO.Handle.Types'
instance Read Newline -- Defined in `GHC.IO.Handle.Types'
instance Read NewlineMode -- Defined in `GHC.IO.Handle.Types'
...plus 25 others
...plus six instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the first argument of `map', namely `read'
In the first argument of `(.)', namely `map read'
In the first argument of `(<$>)', namely `map read . words'
|
9 | nums <- map read . words <$> getLine
| ^^^^
C:\Users\Donatas\Documents\haskell\la3.hs:10:9: error:
* Ambiguous type variable `a0' arising from a use of `print'
prevents the constraint `(Show a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance Show HandlePosn -- Defined in `GHC.IO.Handle'
instance Show BufferMode -- Defined in `GHC.IO.Handle.Types'
instance Show Handle -- Defined in `GHC.IO.Handle.Types'
...plus 27 others
...plus 13 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In a stmt of a 'do' block: print (calculate nums)
In the expression:
do nums <- map read . words <$> getLine
print (calculate nums)
In an equation for `solve':
solve
= do nums <- map read . words <$> getLine
print (calculate nums)
|
10 | print (calculate nums)
| ^^^^^^^^^^^^^^^^^^^^^^
C:\Users\Donatas\Documents\haskell\la3.hs:12:1: error:
* Non type-variable argument in the constraint: Num [a]
(Use FlexibleContexts to permit this)
* When checking the inferred type
calculate :: forall a. (Eq a, Num [a], Num a) => [a] -> a
|
12 | calculate (x:xs) = x + check xs
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
答案 0 :(得分:5)
首先,我建议你默认总是写类型注释。在开始实现任何内容之前,请勾勒出程序的类型。对于这个程序,我建议你从:
开始IO _
这些名字也可能会得到改善,以更好地传达他们正在做的事情。
请注意,只有一个类型为calculate
的函数。这可以隔离程序中不纯净的部分,这将使您的生活更轻松(例如测试,代码推理等)。
你离我不远。只需尝试重新编写代码以适应上述类型。请注意,您在const { exec } = require('child_process');
module.exports = function (options, cb) {
// turn the options to node-sass cli args
// something like this...
exec(`node-sass ${agrs}`, execOptions, cb);
}
实施中错过了一种模式;)
答案 1 :(得分:0)
如果您检查代码并按照类型进行操作,则错误的位置非常清晰。是的,您可以添加类型注释 - 强烈推荐 - 但我发现您的代码非常简单,您可以通过一些等式推理来解决。
以solve
开头,很容易看出nums
的类型为Read a => [a]
,因为您按字词分割字符串(即[String]
)并映射read
过了它。因此,a
的列表就是您向calculate
提供的内容。如您所知,列表是(1)空列表([]
)和(2)由头部构成的cons单元格,类型为a
的元素和尾部之间的不相交和,列表的其余部分((x:xs)
)。
您首先注意到的是缺少空列表的情况;让我们添加它:
calculate [] = 0 -- I assume this is correct
指向calculate
和check
的正文。后者显然期望一个数字,顺便说一下你可以更简洁:
check 0 = -1
check _ = 1
现在,如果您查看calculate
,就会看到您正在调用check
并将其传递给xs
。什么是xs
?它以(x:xs)
模式绑定,这就是你如何解构cons细胞。显然,xs
是单元格的尾部,因此列表本身。但是check
期待一个数字!您可以在此处获得的唯一数字是x
,而不是xs
。因此,让我们将您的代码更改为
calculate (x:xs) = check x + ...
您的规范声明您要迭代列表。只有在使用xs
执行某些操作时才会发生这种情况。你能用它做什么?唯一的答案是递归调用calculate
:
calculate (x:xs) = check x + calculate xs
...通过这些更改,您的代码就可以了。