Man*_*man 2 lisp dictionary haskell functional-programming maybe
为了学习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."
Run Code Online (Sandbox Code Playgroud)
起初,似乎效果很好。例如:
*TextGame> describePath (Lloc "living-room" "east" "door")
"There is door going east from here."
Run Code Online (Sandbox Code Playgroud)
但是当我尝试将该函数应用于列表时,我收到了这个错误:
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)
Run Code Online (Sandbox Code Playgroud)
错误很明显,但我无法解决它。我想解析Maybe的值列表并使用运行良好的函数describePath打印路径:
有任何想法吗?另外,如果有人想分享替代方案或觉得此代码可能更符合 Haskell 风格,请随时讨论。
可能有一些更高级的库助手,但我认为您应该首先学习如何以Maybe最基本(和通用)的方式处理s:使用模式匹配。
case lookup situacio edges of
Nothing -> [] -- not found, how do you want to handle this case?
Just locs -> map describePath locs
Run Code Online (Sandbox Code Playgroud)
通常,人们希望将结果重新包装在另一个中Maybe,例如:
case lookup situacio edges of
Nothing -> Nothing -- not found
Just locs -> Just (map describePath locs)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们可以使用库辅助函数来缩短代码:
map describePath <$> lookup situacio edges
Run Code Online (Sandbox Code Playgroud)