我是Haskell的新手,我正在努力学习基础知识.我需要声明一个名为Pos的类型,它将具有两个整数然后我需要方向北,南,西,东,以便我可以根据方向改变位置.一旦我这样做,我需要创建一个称为移动的函数,它将获取移动列表和初始位置,并在所有移动后返回位置.这是我的代码,但我仍然坚持我必须遍历移动列表.
type Pos = (Int, Int)
data Direction = North | South | East | West
move :: Direction -> Pos -> Pos
move North (x,y) = (x, y+1)
move West (x,y) = (x-1, y)
move South (x,y) = (x, y-1)
move East (x,y) = (x+1, y)
moves :: [Direction] -> Pos -> Pos
moves [] (x,y) = (x,y)
moves (h:xs) (x,y)
| h == North = move North (x,y)
| h == West = move West (x,y)
| h == South = move South (x,y)
| otherwise = move East (x,y)
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
将一系列事物组合成一个东西称为折叠列表.有(大约)两个列表折叠:foldl和foldr.倾向于使用折叠是学习Haskell的重要一步.我们需要foldl,有类型
foldl :: (a -> b -> a) -> a -> [b] -> a
Run Code Online (Sandbox Code Playgroud)
现在foldl通过使用组合函数和初始值来组合列表中的东西,例如
foldl (£) s [x,y,z] = (((s £ x) £ y) £ z)
Run Code Online (Sandbox Code Playgroud)
(l输入foldl是左边的缩写,所以它可以帮助你记住你的起始值s将在左边结束,但更重要的是括号与左边相关联.)
第三个参数是list参数[b].我们将其用于移动列表,因此类型b将是Direction.
第二个参数是类型的起始值a,因此我们将使用它作为您的初始位置,因此类型a将是Pos.
第一个参数是将列表中的内容与当前值组合在一起的函数.现在我们知道的类型b和a是Direction和Pos我们知道,我们的组合函数的类型必须是Pos -> Direction -> Pos.移动函数几乎正是我们需要的,除了我们需要交换参数.该flip功能就是这样flip move,我们需要的类型也是如此.
因此,我们将专门的类型foldl是
foldl :: (Pos -> Direction -> Pos) -> Pos -> [Direction] -> Pos
Run Code Online (Sandbox Code Playgroud)
并定义
moves :: [Direction] -> Pos -> Pos
moves ds i = foldl (flip move) i ds
Run Code Online (Sandbox Code Playgroud)
现在foldl有一个"严格"的版本foldl',在这种情况下更快,所以如果你在快节奏的游戏中使用它,或者处理大量的动作,你会想要使用那个.
与往常一样,您可以通过在hoogle上搜索其名称或类型来查找功能.
还有一个折叠功能,它以不同的方式折叠列表.您可以在这个问题中了解它们之间的区别.简而言之,foldr工作方式如下:
foldr (?) s [x,y,z] = (x ? (y ? (z ? s)))
Run Code Online (Sandbox Code Playgroud)
(rin foldr是对的缩写,所以它可以帮助你记住你的起始值s最终会在右边,但更重要的是括号与右边相关联.)
| 归档时间: |
|
| 查看次数: |
265 次 |
| 最近记录: |