繁体   English   中英

如何处理 Haskell 中的“可能 [值]”列表?

[英]How to deal with a list of 'Maybe [values]' in Haskell?

为了学习 Haskell,我尝试改编康拉德·巴尔斯基 (Conrad Barski) 的名著《Land of Lisp》的一些练习。 这个想法是制作一个简单的文本游戏引擎。

具体我试过:

type Clau = String
type Descripcio = String
type Valors = [String]

-- NOTE : Ideas of types http://learnyouahaskell.com/making-our-own-types-and-typeclasses
data Lloc = Lloc String String String deriving (Show) 
llocSituacio :: Lloc -> String  
llocSituacio (Lloc situacio _ _ ) = situacio  
llocDireccio :: Lloc -> String
llocDireccio (Lloc _ direccio _) = direccio
llocPas :: Lloc -> String
llocPas ( Lloc _ _ pas) = pas

nodes :: [(Clau,Descripcio)]
nodes = [("living-room","you are in the living-room. a wizard is snoring loudly on the couch.")
           ,("garden","you are in a beautiful garden. there is a well in front of you.")
           , ("attic", "you are in the attic. there is a giant welding torch in the corner.")]

edges :: [([Char], [Lloc])]
edges = [ ("living-room", [(Lloc "garden"  "west" "door"), ( Lloc "attic" "upstairs" "ladder") ])
        , ("attic", [(Lloc "living-room"  "east"  "door")])
        , ("garden", [(Lloc "living-room" "east"  "door")])]

describePath :: Lloc -> String  
describePath  e = "There is " ++ llocPas e ++ " going " ++ llocDireccio e ++ " from here." 

起初,它似乎运作良好。 例如:

*TextGame> describePath (Lloc "living-room"  "east"  "door")
"There is door going east from here."

但是当我尝试将 function 应用于列表时,我收到了这个错误:

situacio = "garden"
map (describePath) (lookup situacio edges)



<interactive>:2:22: error:
    • Couldn't match expected **type ‘[Maybe Lloc]’**
                  with actual **type ‘Maybe [Lloc]’**
    • In the second argument of ‘map’, namely ‘(lookup situacio edges)’
      In the expression: map (describePath) (lookup situacio edges)
      In an equation for ‘it’:
          it = map (describePath) (lookup situacio edges)

错误很明显,但我无法解决它。 我想解析可能的值列表并使用运行良好的 function describePath 打印路径:

有任何想法吗? 另外,如果有人想分享替代方案或觉得此代码可能更像 Haskell 风格,请随时讨论。

可能有一些更高级的库助手,但我认为您应该首先学习如何以最基本(和一般)的方式处理Maybe :使用模式匹配。

case lookup situacio edges of
   Nothing   -> [] -- not found, how do you want to handle this case?
   Just locs -> map describePath locs

通常,人们希望将结果重新包装在另一个Maybe中,例如:

case lookup situacio edges of
   Nothing   -> Nothing -- not found
   Just locs -> Just (map describePath locs)

在这种情况下,我们可以使用库助手 function 来缩短代码:

map describePath <$> lookup situacio edges

非常感谢chi,它工作得很好。 我刚做了一个新的function:

describePaths situacio edges = case lookup situacio edges of
    Nothing -> []
    Just locs -> map describePath locs

..并且效果很好:

*TextGame> situacio = "living-room"
*TextGame> describePaths situacio edges
["There is door going west from here.","There is ladder going upstairs from here."]

但我发现我并不完全理解 <$> 运算符。 我遵循以下评论: Haskell 中的 <$> 是什么意思?

所以我遵循建议: https://hoogle.haskell.org/?hoogle=%3C$%3E

这称为函子:

(<$>) :: Functor f => (a->b) -> f a -> f b

这实际上与 fmap 完全相同:

fmap :: Functor f => (a -> b) -> f a -> f b

似乎是一样的:

*TextGame> (*2) <$> [1..3]
[2,4,6]
*TextGame> fmap (*2) [1..3]
[2,4,6]

但是,实际上它们是不同的:

*TextGame> map describePath <$> lookup situacio edges
Just ["There is door going west from here.","There is ladder going upstairs from here."]
*TextGame> fmap (describePath) (lookup situacio edges)

<interactive>:30:22: error:
    • Couldn't match type ‘[Lloc]’ with ‘Lloc’
      Expected type: Maybe Lloc
        Actual type: Maybe [Lloc]
        ....

有人可以多说一点吗? 我不完全明白为什么'fmap(describePath)(查找位置边缘)'不起作用? (我正在玩 Maybe's 和 Just's 但是......)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM