2015-04-28 3 views
2

Новичок Haskeller здесь. Я пытаюсь представить pizza equation с простой программой командной строки, которая принимает несколько человек и возвращает соответствующее количество пицц на заказ. Я знаю, что мне нужно преобразовать свой вход (IO String) в Int, а затем преобразовать результат в строку, используя show. Как мне IO String -> Int? Или я скинирую эту кошку не так?Базовый Haskell IO (IO String -> Int)?

import System.Environment 
import System.IO 

pizzas :: Integral a => a -> a 
pizzas x = div (x * 3) 8 

main = do 
    putStrLn "How many people are you going to feed?" 
    arg <- getLine 
    -- arg needs to IO String -> Int 
    -- apply pizzas function 
    -- Int -> String 
    putStrLn "You will need to order " ++ string ++ " pizzas." 
+4

Кажется, вы собрали здесь несколько хороших ответов, давая вам хорошие советы. Так что просто на общем боковом пути: в любое время, когда вы начинаете думать «IO foo -> bar», вы должны нервно косить. Вы не можете (* кашель, кашель *) выйти из ИО после того, как вы вошли, и это хорошо. –

+0

Я не уверен, что понимаю ... Я понял, что Haskell работает как: 'Input -> [Purely Functional Magic] -> Output ', где безопасное склеивание чистого кода и нечистых данных было целым. Или есть просто более идиоматический способ, которым я мог бы выразить эту проблему? – Daniel

+1

@ Даниэль Да, это примерно право. Но ... вы не можете * действительно * перейти от 'IO a' к' a', за исключением функции, которая фактически возвращает тип 'IO a'; скорее, так, как вы делаете, это написать функцию 'f x = y', а затем внутри' main' вы делаете что-то вроде 'x <- readX; putStrLn (f x) '. Здесь 'x'« извлекается »из« IO »и передается вашей чистой программе (' f'), поэтому остальная часть вашего кода может быть чистой. Но вы можете делать такие вещи только внутри функции, которая может выполнять IO; вы не можете * вообще * конвертировать 'IO a' в' a'. – amalloy

ответ

2

Использование чтения будет преобразовывать тип из строки, если это возможно

соответствующего типа А с помощью шоу преобразует целое число в это строковое представление

arg <- getLine 
let num = pizzas (read arg) 
putStrLn $ "You will need to order " ++ (show num) ++ " pizzas." 

Или это:

arg <- readLn :: IO Int 
let num = pizzas arg 
putStrLn $ "You will need to order " ++ (show num) ++ " pizzas." 
+3

@ Daniel Этот ответ технически корректен, но здесь следует понимать, что когда вы выполняете 'arg <- getLine',' arg' имеет тип 'String', потому что операция привязки« извлекает »значение из контейнера« IO » , Затем вы можете просто «прочитать arg» и отправить это как аргумент «pizzas», и в это время Haskell выведет правильный тип. – Yawar

+0

Я получаю: 'parse error on input '='' с обоими решениями: ~/ – Daniel

+0

@Daniel См. Edit – smac89