我正在尝试编写一些IO Package 函数。
我当前的代码(有效)是:
getUserHome :: IO String
getUserHome = do
usr_id <- getRealUserID
homeDirectory <$> getUserEntryForID usr_id
我正在寻找的是一个更方便的符号(一个没有使用do
-关键字)。
如果没有任何的Monadic沙拉我只会写
getUserHome = homeDirectory . getUserEntryForID . getRealUserID
我猜.
有一个替代运算符,它尊重单子......但是在我所有的搜索中,我没有找到它。
我尝试了<$>
,但这似乎不是我想要的:
src/Main.hs:49:21: error:
• Couldn't match type ‘IO UserEntry’ with ‘UserEntry’
Expected type: UserID -> UserEntry
Actual type: UserID -> IO UserEntry
• In the second argument of ‘(<$>)’, namely ‘getUserEntryForID’
In the first argument of ‘(<$>)’, namely
‘homeDirectory <$> getUserEntryForID’
In the expression:
homeDirectory <$> getUserEntryForID <$> getRealUserID
|
49 | homeDirectory <$> getUserEntryForID <$> getRealUserID -- usr_id
2条答案
按热度按时间zpjtge221#
您可以使用
>>=
,因为Haskell最终会将do
块“反糖化”为:这可以简化为:
或:
aiqt4smr2#
首先要考虑类型:
现在您可以:
1.将
getRealUserID
应用于getUserEntryForID
。这是一个直接适合于事实上,如果你想让它看起来像一个合成链,我更喜欢翻转的版本,即。
1.将
homeDirectory
应用于此。在您的情况下,这根本不是一元的,所以您需要使用fmap
或<$>
来提升它。请考虑运算符的优先级。因为单子是关联的,你也可以反过来做:
1.用
getUserEntryForID
合成homeDirectory
。后者已经是标准的 *Kleisli箭头 *,为了使用Kleisli合成运算符,您也可以将homeDirectory
提升到Kleisli:1.同样,将整个过程应用到
getRealUserID
:事实上,你也可以把
getRealUserID
变成Kleisli箭头,用一个伪参数()
。这种风格在Haskell中相当少见,但它的优点是Kleisli组合的结合性变得明显,就像普通函数组合一样明显: