Преобразуйте getArgs из IO [String] в IO [Int] - PullRequest
0 голосов
/ 11 сентября 2018

Я хотел бы написать программу, подобную следующей:

add :: Int -> Int -> Int
add a b = a + b

main :: IO ()
main = do
    args <- getIntArgs
    case args of
        [a,b] -> putStrLn $ show $ add a b

Есть ли способ, которым я могу написать функцию getIntArgs в терминах getArgs (из System.Environment)?

1 Ответ

0 голосов
/ 11 сентября 2018

Сначала разверните его в своей голове. Вам нужна функция, которая идет от IO [String] -> IO [Int]. Сначала рассмотрим функцию, которая идет от f a -> f b - ну это fmap!

Тогда нам просто нужно найти функцию, которая начинается с a -> b. В этом случае a ~ [String] и b ~ [Int]. Теперь мы видим другой функтор, обертывающий наши конкретные типы - fmap снова работает, на этот раз абстрагируя [] вместо IO.

Теперь нам нужна функция, которая выходит String -> Int. Это read.

getIntArgs = fmap (fmap read) getArgs

начиная с f (g x) = (f . g) x, мы можем написать (и должны предпочесть, это Haskelly-er): (fmap . fmap) read $ getArgs.

На самом деле вся ваша функция просто:

main :: IO ()
main = (fmap (sum . fmap read) getArgs) >>= print
-- assuming you're okay replacing `(+)` with `sum`

-- if not:
main = (fmap (uncurry (+) . listToTuple . fmap read) getArgs) >>= print
  where
  listToTuple [a, b] = (a, b)
...