我想读取一个String和toUpper所有字符。
import Data.Char
main = do
a <- getLine
b <- getLine
map toUpper a
if (a == b)
then print 0
else if (a < b)
then print (-1)
else print 1
然后我得到了这个
Couldn't match expected type `IO a0' with actual type `[b0]'
In the return type of a call of `map'
In a stmt of a 'do' expression: map toUpper a
In the expression:
do { a <- getLine;
b <- getLine;
map toUpper a;
if (a == b) then
print 0
else
if (a < b) then print (- 1) else print 1 }
我可以使用来自getLine的String的地图吗? 或者有另一种方法来读取字符串和上述所有字符?
答案 0 :(得分:7)
您没有分配&#34;结果&#34;你的map
号召唤任何东西。这导致了您遇到的类型错误,它告诉您正在尝试返回一个字符串(map
调用的结果),当它确实需要某种IO
类型时。 / p>
直接修复看起来像这样:
import Data.Char
main = do
a <- getLine
b <- getLine
let c = map toUpper a
if (c == b)
then print 0
else if (c < b)
then print (-1)
else print 1
如果你使用fmap
,你可以toUpper
所有字符并同时获取输入行(防止需要c
)。
import Data.Char
main = do
a <- fmap (map toUpper) getLine
b <- getLine
if a == b
then print 0
else if a < b
then print (-1)
else print 1
答案 1 :(得分:7)
其他人已经以最小的方式纠正了你的程序,但我想指出Haskell已经改进的C-ism:
if (a == b)
then print 0
else if (a < b)
then print (-1)
else print 1
是否曾经困扰过你数字被用于记录事物的比较?这肯定困扰着我。幸运的是,在Haskell中定义新数据类型非常便宜,我们一直都在这样做。在标准库中,有一个类型定义如下:
data Ordering = LT | EQ | GT
还有一个标准功能
compare :: Ord a => a -> a -> Ordering
那么为什么不使用这个美丽的Haskell工件?
main = do
a <- getLine
b <- getLine
print (compare (map toUpper a) b)
答案 2 :(得分:4)
最小的改进是将print
向外移动:
print $ if (a == c)
then 0
else if (a < b)
then (-1)
else 1
至于惯用解决方案,考虑在一个单独的函数中分离所有非monadic代码(比较和大写)。
此外,如果您在代码中看到elsif
,请考虑警卫:
c_compare a c
| a == c = 0
| a < c = -1
| otherwise = 1
案例实施也是可能的:
c_compare a c = case (compare a c) of
LT -> -1
EQ -> 0
GT -> 1
答案 3 :(得分:2)
请记住,Haskell中的所有内容都是不可变的,因此调用map toUpper a
实际上并不会修改a
。如果您想保存该结果,则必须将其绑定到let
子句中的变量。因此,您可能希望将代码更改为以下内容:
import Data.Char
main = do
a <- getLine
b <- getLine
let c = map toUpper a
if (a == c)
then print 0
else if (a < b)
then print (-1)
else print 1