2011-11-10 28 views
2

我想讀取一個String和toUpper的所有字符。如何使用從getLine獲取的字符串的映射?[Haskell]

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有一個字符串映射? 或者還有另一種方式來讀取一個字符串,並上傳所有的字符?

+0

將電梯FX =回報(FX)的函數getline >> =電梯(地圖toUpper) –

回答

7

您並未將您的map調用的「結果」分配給任何事情。這導致了您收到的類型錯誤,它告訴您,您正嘗試返回一個字符串(map調用的結果),當它真的需要是某種IO類型時。如果您使用fmap可以toUpper所有的字符,讓輸入線在同一時間(防止了c的需要)

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 

直接的解決將是這個樣子。

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 
+0

非常感謝! – wysoviet

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 
+0

非常感謝! – wysoviet

7

其他人在最小的方式修正你的計劃,但我想指出一個C-主義是哈斯克爾有所改善:

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 

那麼爲什麼不利用這個美麗的哈斯克爾神器?

main = do 
    a <- getLine 
    b <- getLine 
    print (compare (map toUpper a) b) 
+0

我打算提到這一點,但我不確定OP是否需要0,1和-1的值。除此之外,你的版本更好。 –

+0

查看下面的'fromEnum'技巧 – nponeccop

+0

@nponeccop,啊謝謝...我雖然可能存在類似的東西,但我找不到它。 (我想我應該使用hoogle :),快速搜索返回'fromEnum') –

4

在Haskell中,將非一元代碼與單代代碼分開是一種很好的做法。

一個很小的改進是向外移動print

print $ if (a == c) 
    then 0 
    else if (a < b) 
     then (-1) 
     else 1 

作爲慣用溶液,認爲在一個單獨的功能(包括比較和uppercasing)分離所有非一元代碼。

另外,如果你在你的代碼中看到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 
+2

或(相當可怕)'c_compare a c = fromEnum(compare a c) - 1'。 – augustss

+0

我會說這是棘手的,但並不可怕 – nponeccop

相關問題