Dictionary 如何处理';也许[价值观]';在哈斯克尔?

Dictionary 如何处理';也许[价值观]';在哈斯克尔?,dictionary,haskell,functional-programming,lisp,maybe,Dictionary,Haskell,Functional Programming,Lisp,Maybe,为了学习哈斯克尔,我试着改编康拉德·巴尔斯基(Conrad Barski)的名著《Lisp之地》(Land of Lisp)中的一些练习。其想法是制作一个简单的文本游戏引擎 具体地说,我试过: type Clau = String type Descripcio = String type Valors = [String] -- NOTE : Ideas of types http://learnyouahaskell.com/making-our-own-types-and-typecla

为了学习哈斯克尔,我试着改编康拉德·巴尔斯基(Conrad Barski)的名著《Lisp之地》(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."
但当我尝试将该函数应用于列表时,出现了以下错误:

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)
situacio=“花园”
映射(描述路径)(查找位置边缘)
:2:22:错误:
•无法匹配预期的**类型“[可能是Lloc]”**
使用实际**类型“可能[Lloc]”**
•在“映射”的第二个参数中,即“(查找位置边缘)”
在表达式中:映射(描述路径)(查找位置边)
在“it”的方程式中:
it=映射(描述路径)(查找位置边缘)
错误很明显,但我没有设法解决它。我想解析Maybe的值列表,并使用功能describePath打印路径,该功能运行良好:


有什么想法吗?另外,如果有人想分享替代方案,或者觉得此代码可能更符合Haskell风格,请随意讨论。

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

case查找的situacio边
Nothing->[]--未找到,您希望如何处理此案例?
仅locs->地图描述路径locs
通常情况下,一个人希望在另一个
中重写结果,可能是
,例如:

case lookup situacio edges of
   Nothing   -> Nothing -- not found
   Just locs -> Just (map describePath locs)
在这种情况下,我们可以使用library helper函数来缩短代码:

map describePath <$> lookup situacio edges
映射描述路径查找位置边缘

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

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."]
但我发现我并不完全理解接线员。我遵循以下意见:

因此,我遵循以下建议:

这就是所谓的函子:

(<$>) :: Functor f => (a->b) -> f a -> f b
看起来是一样的:

*TextGame> (*2) <$> [1..3]
[2,4,6]
*TextGame> fmap (*2) [1..3]
[2,4,6]
*TextGame>(*2)[1..3]
[2,4,6]
*text游戏>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]
        ....
*TextGame>地图描述路径查找位置边缘
只是[“有门从这里往西走。”,“有梯子从这里往楼上走。”]
*text游戏>fmap(描述路径)(查找现场边缘)
:30:22:错误:
•无法将类型“[Lloc]”与“Lloc”匹配
预期类型:可能是Lloc
实际类型:可能[Lloc]
....
谁能再亮一点吗?我不完全理解为什么“fmap(描述路径)(查找位置边缘)”不起作用?
(我在玩“也许”和“只是”的游戏,但是…

非常感谢您的回答!它工作得很好!但我意识到,我并没有完全理解操作员,这是不同的fmap权利!?它包括你指出的模式!?这就是区别@Mandorman
fx
正是
fmap fx
Maybe
函子:它只在“a
下应用
f
,并保持
不变。您从上一个示例中删除了
map
,正确的翻译是
fmap(map descripbepath)(查找位置边缘)
。这里的
fmap
处理
Maybe
map
处理
[Lloc]
中的列表。哦,我明白了!我现在明白了!。多谢各位!也许这个古老的答案有帮助?是的,不是。
*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]
        ....