Haskell - Печать номеров - PullRequest
       2

Haskell - Печать номеров

2 голосов
/ 19 октября 2011

Я написал следующий код:

module Test where

import Char
import IO

main = do
    str <- readFile "no.txt"
    putStrLn (show(english str))

string2list :: String -> [String]
string2list "" = []
string2list s = words s


english :: String -> Int
english s
    | head (string2list s) == "one"     = 1
    | head (string2list s) == "two"     = 2
    | head (string2list s) == "three"   = 3
    | head (string2list s) == "four"    = 4
    | head (string2list s) == "five"    = 5
    | head (string2list s) == "six"     = 6
    | head (string2list s) == "seven"   = 7
    | head (string2list s) == "eight"   = 8
    | head (string2list s) == "nine"    = 9
    | otherwise                         = error "not match"

И в no.txt:

one
two
three
four
....

После компиляции и запуска кода, я получил результат:

1

Но я ожидаю получить:

1
2
3
4
...

Что не так с кодом?Любая помощь?ТНХ!

Ответы [ 3 ]

6 голосов
/ 19 октября 2011

str - это не список строк (это просто строка типа one\ntwo) при чтении из readFile. У

main = do
    str <- readFile "no.txt"
    mapM_ (\x -> putStrLn (show(english x))) $ lines str

в вашем main и конвертируйте str в список, используя lines (см. Документ строк ).

5 голосов
/ 19 октября 2011

Это не ответ на ваш вопрос, а скорее стилистический совет.Вы можете избавиться от этих многословных head (string2list s) вещей, используя сопоставление с образцом и заменив string2list на words;оба делают одно и то же:

english s = case words s of
  "one"   :_ -> 1
  "two"   :_ -> 2
  "three" :_ -> 3
  "four"  :_ -> 4
  "five"  :_ -> 5
  "six"   :_ -> 6 
  "seven" :_ -> 7
  "eight" :_ -> 8 
  "nine"  :_ -> 9
  _          -> error "no match"
2 голосов
/ 20 октября 2011

Ваша проблема в том, что english смотрит только на первое слово.Ваш файл поступает как

"one\ntwo\nthree\nfour"

Затем words превращает это в:

["one","two","three","four"]

Использование головы, которая дает вам:

"one"

И для этого 1 напечатано.

Instaid мы хотели бы использовать английский для всех слов.Именно тогда map пригодится, но в этом случае мы отображаем действие ввода-вывода в список, поэтому мы хотим использовать mapM.Кроме того, нас не интересует результат действия ввода-вывода (мы просто хотим, чтобы это действие произошло), поэтому мы используем mapM_:

import Control.Monad

main = do
  str <- readFile "no.txt"
  mapM_ (print . english) (words str)

english "one"   = 1
english "two"   = 2
english "three" = 3
english "four"  = 4
english "five"  = 5
english "six"   = 6 
english "seven" = 7
english "eight" = 8 
english "nine"  = 9 

Обратите внимание, что можно написать это с помощью map instaidиз mapM, сначала сделав ["one","two","three",...] в ["1","2","3"], объединяя эти строки, а затем используя putStrLn, но описанный выше способ является и более коротким, и более идиоматическим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...