import Data.Char
import Data.List
-- 1 2 3 4 5 6 7 8
colors = [1,2,3,4,5]
--game :: [Integer] -> [Char]
game a = do
let black = test a color
white = (test2 a color) - black
let x = [a] ++ createScore black white
show x
test [] [] = 0
test (x:xs) (y:ys) = if x == y then 1+test xs ys else 0+test xs ys
test2 a b = length (intersection a b)
intersection first second = [n | n <- first , isInfixOf [n] second]
createScore c b = [(take c (repeat 1) ++ take b (repeat 0))]
start = do
a <- getLine
let b = map read $ words a
--print b
game b
start
我遇到IO和nonIO功能问题。 该计划的描述:
问题在于功能开始,我不知道如何解决它。
感谢您的帮助。
答案 0 :(得分:3)
有些事情与您提供给我们的代码无关。
我将解决编译错误。
首次加载时,我们收到名称错误:
ex1.hs:10:26:
Not in scope: 'color'
Perhaps you meant 'colors' (line 6)
(再次在第11行)
当然编译器是正确的,我们只需要更改相应的名称即可。
接下来,我们假设您在IO和非IO功能方面提到了有趣的一个:
ex1.hs:28:7:
Couldn't match type '[]' with 'IO'
Expected type: IO Char
Actual type: String
In the return type of a call of 'game'
In a stmt of a 'do' block: game b
In the expression:
do { a <- getLine;
let b = map read $ words a;
game b;
start }
错误是您在game b
阻止中使用IO
。
您对game
的函数定义注释掉的类型注释实际上是正确的 - 它是[Integer] -> [Char]
。
因此它是一个纯粹的功能,我们不需要使用do
符号来描述它,就像我们处理IO的东西一样 - 因为你在这里使用了符号使用列表的参数,do
表达式表示列表上下文中的计算,而不是IO计算,因此从start
调用它具有类型不匹配,它期望IO
,但它找到了[]
。
我们可以使用game
表达式将let-in
转换为纯函数来开始修复它。
game :: [Integer] -> [Char]
game a = let black = test a colors
white = (test2 a colors) - black
x = [a] ++ createScore black white
in show x
所以现在我们有一个函数返回输入的字符串及其得分。
编译器现在提供错误Expected type: IO Char, Actual type: [Char]
,这是因为我们仍在尝试在主do
块中使用非IO表达式。
我们可以通过将字符串实际打印到stdout
来解决这个问题,只需使用print,这样你的原始
--print b
game b
可以
print $ game b
此时程序编译!
不幸的是,它仍然不太正确,当我们运行它并输入1 2 3
之类的整数列表时,我们得到异常ex1.hs:(14, 1)-(15,66): Non-exhaustive patterns in function test
。
这个归结为您对test
的定义:
test [] [] = 0
test (x:xs) (y:ys)
没有考虑到一个列表为空的可能性 - 因为检查总是在列表的头元素之间进行,可能是解决这个问题的最小修改可能只是:
test (x:xs) (y:ys) = if x == y then 1+test xs ys else 0+test xs ys
test _ _ = 0
现在程序编译并执行。希望这是有道理的。
答案 1 :(得分:0)
game
是(或应该是)纯函数,因此您需要使用在start
函数中返回IO值的函数来调用它,例如: G。 print $ game b
。
也没有理由在那里使用do
符号(你可以因为[a]
也是monad,但你不能以任何方式利用它)。您可以使用game a = show x
并将let
语句替换为where
块(或使用let
... in
)。
test
应该能够处理一个列表为空而另一个列表为空的情况,或者您需要确保两个列表的大小始终相同。