【发布时间】:2015-12-08 11:02:29
【问题描述】:
我尝试通过自己的练习找到解决方案,并满足以下要求:
- 我们需要根据给定的顺序移动对象。
- 序列由动作组成。
以下是可能的动作:F、L、R
- F:前进
- L : 向左旋转 90°
- R:向右旋转 90°
然后用字符串表示一个序列,如下所示:
"FFLRLFF"
我想解析上述序列(并处理错误),然后将每个操作绑定到一个函数,如下所示:
parseAction :: Char -> Either String (a -> a)
parseAction 'F' = Right moveForward
parseAction 'L' = Right turnLeft
parseAction 'R' = Right turnRight
parseAction s = Left ("Unkown action : " ++ [s])
-- Implementation omitted
moveForward :: a -> a
turnLeft :: a -> a
turnRight :: a -> a
现在我想要的是具有以下签名的东西:
parseSequence :: String -> Either String [(a -> a)]
我想通过多次使用parseAction 函数来解析一个完整的序列,并在该函数返回 Left 时失败。我不知道如何实现这个功能。
你有什么想法吗?
【问题讨论】:
-
我本来打算推荐 Hoogle,但我发现让 Hoogle 给我正确答案非常困难。我从
(Char -> Either String (a -> a)) -> (String -> Either String [(a -> a)])开始,但这给出了结果;获得正确答案需要我可以用更多多态的a替换a -> a,以及我可以用更多多态的f替换Either String。直到那时它才建议mapM。哦,好吧,至少我不必知道Char和String可以替换为更多态的b和[b]。 -
id不是a -> a类型的唯一有效函数吗? (忽略错误、未定义、不安全的副作用等)