gpt4 book ai didi

haskell - 如何将 (Either String (a -> b)) 映射到 (Either String [(a -> b)])

转载 作者:行者123 更新时间:2023-12-04 09:34:59 28 4
gpt4 key购买 nike

我尝试通过自己的练习找到解决方案,并满足以下要求:

  • 我们需要根据给定的序列移动对象。
  • 序列由 Action 组成。

  • 以下是可能的操作:F、L、R
  • F:前进
  • L : 向左旋转 90°
  • R : 向右旋转 90°

  • 一个序列然后由一个字符串表示,如下所示:
    "FFLRLFF"
    我想解析上述序列(并处理错误),然后将每个操作绑定(bind)到一个函数,如下所示:
    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 时失败。我被困在如何实现这个功能上。

    你有什么想法 ?

    最佳答案

    这看起来像

    mapM :: Monad m => (a -> m b) -> [a] -> m [b]

    在哪里
    a ~ Char
    b ~ (a -> a)
    m ~ (Either String)

    所以一个实现很简单:
    parseSequence :: String -> Either String [a -> a]
    parseSequence = mapM parseAction

    顺便说一句,请注意您的 parseAction真的不想使用类型 (a -> a) ,它必须适用于任何类型 a ,由调用函数的人选择。相反,您希望它使用类型 (Location -> Location) , 其中 Location 是您用来表示您正在移动的对象的位置的任何类型。

    等效于 mapM,您可以(如 duplode 所建议的那样)改为使用 traverse,这稍微更通用。在最近版本的 GHC 中,traverse 在 Prelude 中;在旧版本中,您可能必须从 Data.Traversable 导入它才能使用它。

    关于haskell - 如何将 (Either String (a -> b)) 映射到 (Either String [(a -> b)]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32531008/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com