List 如何将'n'表示为一系列数字
我有以下功能:List 如何将'n'表示为一系列数字,list,variables,haskell,types,List,Variables,Haskell,Types,我有以下功能: type Coordin = (Int,Int) data Grid = Open | Taken Int myOwn :: Coordin -> Grid -> Bool myOwn (x,y) grid | ((board)!!(y)!!(x)) == Taken n = True | otherwise = False isTaken
type Coordin = (Int,Int)
data Grid = Open
| Taken Int
myOwn :: Coordin -> Grid -> Bool
myOwn (x,y) grid
| ((board)!!(y)!!(x)) == Taken n = True
| otherwise = False
isTaken (Taken _) = True
isTaken Open = False
我想
n
表示任何数字(因为Int
在数据网格中被指定为该特定类型的数字),但这件事就是行不通!!我曾考虑使用where
子句,但如果还有其他想法,我将不胜感激。谢谢。保护后的表达式是布尔谓词,而不是模式绑定。因此,您无法将获取的n
与计算值匹配,并将值绑定到n
本质上,防护装置相当于:
myOwn (x,y) grid = if board !! y !! x == Taken n
then True
else False
除了多余的if
语句之外,很明显在这种上下文中不能绑定n
要实现您的目标,您需要另一个模式匹配:
myOwn (x,y) grid = case board !! y !! x of
Taken n -> True
...
但是,由于您实际上没有在此处使用n
的值,因此最好编写一个单独的函数:
type Coordin = (Int,Int)
data Grid = Open
| Taken Int
myOwn :: Coordin -> Grid -> Bool
myOwn (x,y) grid
| ((board)!!(y)!!(x)) == Taken n = True
| otherwise = False
isTaken (Taken _) = True
isTaken Open = False
…然后用它来守卫
顺便说一句,在风格上,你的表达中有很多丑陋的多余括号;您应该删除这些内容。灵感来自camccann的解决方案:
type Board = [[Grid]]
isTaken :: Grid -> Bool
isTaken (Taken _) = True
isTaken Open = False
myOwn :: Coordin -> Board -> Bool
myOwn (x,y) board = isTaken (board !! y !! x)
有没有一种方法可以将
isTaken
和myOwn
组合成一个函数?@maclunian:你可能想用isTaken
定义myOwn
,就像@Tarrasch写的那样。但是没有理由有一个单一的定义,因为isTaken
和索引网格在概念上是不同的操作,如果将isTaken
分开,可读性更高。有没有办法将isTaken
和myOwn
组合成一个函数?@maclunian是的,“但把事情分成几个小函数是很好的。”麦克鲁尼安,我的朋友,请三思。如果您以后再次需要isTaken
,该怎么办?如果合并这两个函数,则不会有任何isTaken
。现在,假设您重复使用了几次isTaken
,3个月后,您更改了datagrid=
,以同时包含一个构造函数retakeint
。然后必须仅在代码中的一个位置更新isTaken
。这就是模块化,也是我们喜欢哈斯克尔的原因我希望你不介意这种批评,但尽管这个答案从根本上说不是错的,但它并不理想Grid
没有Eq
实例,虽然当前可以给它一个实例,但在这里不需要它。想象一下,稍后的重构添加了第三个构造函数partlytake(Int->Grid)
,它定义了在向位置添加内容时发生的情况;这会阻止派生Eq
,但不会阻止编写isOpen
谓词,就像isNothing
不需要Eq
一样。总之,当你真正想要的是案例分析时,最好避免使用(==)
。我不知道为什么这被否决了。这不是最好的解决方案,但它仍然以一种相当简单的方式实现了问题中的函数应该做的事情。。。