我正在编写一个快速响应式系统,其中包含了 Maybe a、IO a 和 MaybeT IO a 的各种组合,并且有很多东西需要考虑。一些没有无效输入的 IO 操作(因此不包含在 MaybeT 中),一些是(并返回 MaybeT IO a)一些不是 IO 操作但可能失败,因此返回 Maybe a,还有一些这只是简单的值,并且开始似乎我必须记住过度组合<$>, Just, fmap, MaybeT, lift, =<<,
并且return
只是为了使所有内容都成为正确的类型。有没有更简单的方法来管理这个或推理我需要使用哪些函数来获取我需要的值?还是我只希望随着时间的推移我会变得更好?这是我的例子:
getPiece :: Player -> Board -> MaybeT IO Piece
getPiece player@(Player pieces _ _ _) board = piece
where
promptString = displayToUserForPlayer player board ++ "\n" ++ (display player) ++ "\n" ++ "Enter piece number: "
input :: MaybeT IO String
input = lift $ prompt promptString
index :: MaybeT IO Int
index = MaybeT <$> return <$> ((fmap cvtFrom1indexedInt) . maybeRead) =<< input
piece :: MaybeT IO Piece
piece = MaybeT <$> return <$> maybeIndex pieces =<< index
getRotatedPiece :: Player -> Board -> MaybeT IO Piece
getRotatedPiece player@(Player pieces _ _ _) board = piece
where
promptString :: MaybeT IO String
promptString = (++) <$> displayListString <*> restOfString
input :: MaybeT IO String
input = MaybeT <$> (fmap Just) <$> prompt =<< promptString
index :: MaybeT IO Int
index = MaybeT <$> return <$> ((fmap cvtFrom1indexedInt) . maybeRead) =<< input
piece :: MaybeT IO Piece
piece = MaybeT <$> return <$> maybeIndex pieces =<< index
rotatedPieceList :: MaybeT IO [Piece]
rotatedPieceList = rotations <$> getPiece player board
displayListString :: MaybeT IO String
displayListString = displayNumberedList <$> rotatedPieceList
restOfString :: MaybeT IO String
restOfString = MaybeT <$> return <$> Just $ "\nEnter rotation number:"
我必须说,我对缺乏简洁性感到失望,即使我删除了类型提示,我也可能会编写一个更短的函数来在 C# 或 python 中做同样的事情