问题描述
我想编写一个函数来读取没有Int
表示法的do
。它可以工作(请参阅下文),但是我想知道readMaybe
周围的内容是否可以以无点形式编写(或以其他方式清除)?
main :: IO ()
main = getLine >>= (\x -> return $ (readMaybe x :: Maybe Int)) >>= print
解决方法
第1步:将lambda替换为无点等效项:
main :: IO ()
main = getLine >>= return . (readMaybe :: String -> Maybe Int) >>= print
步骤2:将m >>= return . f
替换为f <$> m
:
main :: IO ()
main = (readMaybe :: String -> Maybe Int) <$> getLine >>= print
步骤3:将f <$> m >>= g
替换为m >>= g . f
:
main :: IO ()
main = getLine >>= print . (readMaybe :: String -> Maybe Int)
第4步:使用类型应用程序,而不要写出长而笨拙的类型:
{-# LANGUAGE TypeApplications #-}
main :: IO ()
main = getLine >>= print . readMaybe @Int
除了在第2步和第3步中使用<$>
之外,您还可以仅使用monad定律来完成此操作,如下所示(在第1步之后进行选择):
将m >>= f >>= g
替换为m >>= \x -> f x >>= g
(关联性):
main :: IO ()
main = getLine >>= \x -> (return . (readMaybe :: String -> Maybe Int)) x >>= print
简化.
:
main :: IO ()
main = getLine >>= \x -> return ((readMaybe :: String -> Maybe Int) x) >>= print
将return x >>= f
替换为f x
(左侧身份):
main :: IO ()
main = getLine >>= \x -> print ((readMaybe :: String -> Maybe Int) x)
现在,只需将新的lambda替换为它的无点等效,就可以在与步骤3完全相同的位置结束。