点免费版本供阅读

问题描述

我想编写一个函数来读取没有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完全相同的位置结束。