【问题标题】:how to represent `n` as a series of numbers如何将“n”表示为一系列数字
【发布时间】:2011-09-02 00:59:39
【问题描述】:

我有以下功能:

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

我希望n 表示任何数字(因为Int 在该特定类型的数据网格中被指定为这样),但是这不起作用!我考虑过使用where 子句,但如果有任何其他想法,将不胜感激。谢谢。

【问题讨论】:

    标签: list variables haskell types


    【解决方案1】:

    守卫后的表达式是布尔谓词,而不是模式绑定。所以你不能将Taken 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 的值,因此最好编写一个单独的函数:

    isTaken (Taken _) = True
    isTaken Open = False
    

    ...然后用那个守卫,而不是。

    顺便说一句,就文体而言,你的守卫表达中有很多丑陋的多余括号;你应该删除那些。

    【讨论】:

    • 有没有办法可以将isTakenmyOwn 组合成一个函数?
    • @maclunian:您很可能想使用isTaken 定义myOwn,就像@Tarrasch 所写的那样。但是没有理由有一个单一的定义,因为isTaken 和索引网格在概念上是不同的操作,并且将isTaken 分离出来更具可读性。
    【解决方案2】:

    灵感来自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)
    

    【讨论】:

    • 有什么方法可以将isTakenmyOwn 组合成一个函数?
    • @maclunian 是的,但是把事情分解成小函数很好。
    • @maclunian,我的朋友三思而后行。如果您以后再次需要isTaken 怎么办?如果合并这两个函数,您将没有任何isTaken。现在,假设您重复使用isTaken 几次,3 个月后您将data Grid = 更改为还包含一个构造函数ReTaken Int。然后您必须仅在代码中的一处更新isTaken。这就是模块化,也是我们喜欢 haskell 的原因。 :)
    【解决方案3】:
    myOwn (x,y) grid = not (board !! y !! x  == Open)
    

    【讨论】:

    • 我希望你不要介意批评,但虽然这个答案根本上没有错,但它并不理想。 Grid 没有 Eq 实例,虽然目前可以一个,但这里没有必要。想象一下,稍后的重构添加了第三个构造函数PartlyTaken (Int -> Grid),它定义了向某个位置添加内容时会发生什么;这会阻止派生Eq,但不应阻止编写isOpen 谓词,就像isNothing 不需要Eq 一样。总之,当您真正想要的是案例分析时,最好避免使用(==)
    • 我不知道为什么这被否决了。这不是最好的解决方案,但它仍然可以以相当简单的方式完成问题中的功能应该做的事情......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-11
    • 2021-06-16
    相关资源
    最近更新 更多