【问题标题】:Point free version for readMaybereadMaybe的免费版本
【发布时间】:2020-10-06 01:10:52
【问题描述】:

我想编写一个函数来读取没有do 符号的Int。它可以工作(见下文),但我想知道 readMaybe 周围的位是否可以以无点形式编写(或以其他方式清理一下)?

main :: IO ()
main = getLine >>= (\x -> return $ (readMaybe x :: Maybe Int)) >>= print 

【问题讨论】:

    标签: haskell monads pointfree


    【解决方案1】:

    第 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 &lt;$&gt; m &gt;&gt;= g 替换为 m &gt;&gt;= g . f

    main :: IO ()
    main = getLine >>= print . (readMaybe :: String -> Maybe Int)
    

    第 4 步:使用类型应用程序,而不是写出冗长、笨拙的类型:

    {-# LANGUAGE TypeApplications #-}
    
    main :: IO ()
    main = getLine >>= print . readMaybe @Int
    

    作为在第 2 步和第 3 步中使用 &lt;$&gt; 的替代方法,您可以仅使用 monad 法则来完成相同的操作,如下所示(在第 1 步之后继续):

    m &gt;&gt;= f &gt;&gt;= g 替换为m &gt;&gt;= \x -&gt; f x &gt;&gt;= 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 &gt;&gt;= f 替换为f x(左身份):

    main :: IO ()
    main = getLine >>= \x -> print ((readMaybe :: String -> Maybe Int) x)
    

    现在只需将新的 lambda 替换为它的无点等效项,您最终会回到与第 3 步完全相同的位置。

    【讨论】:

    • 这很酷,谢谢!我真的很想保持get input &gt;&gt;= parse &gt;&gt;= something &gt;&gt;= something &gt;&gt;= print 形式的结构,有什么想法可以在这种情况下简化(\x -&gt; return $ (readMaybe x :: Maybe Int))
    • @zoran119 你可以这样做getLine &gt;&gt;= return . readMaybe @Int &gt;&gt;= print
    • @zoran119 如果您想摆脱类型应用程序,可以将readMaybe @Int 替换为(readMaybe :: String -&gt; Maybe Int)
    • @zoran119 readMaybe x 是这样,但我没有指定它的类型。我指定了 readMaybe 的类型。
    • @zoran119,您应该在Control.Monad 中了解&gt;=&gt;&lt;=&lt;。它们非常适合无点单子的东西。
    猜你喜欢
    • 2020-08-03
    • 2012-05-25
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多