【问题标题】:How to avoid writing trivial data type check functions如何避免编写琐碎的数据类型检查函数
【发布时间】:2019-01-28 02:47:29
【问题描述】:

例如,我在 Haskell 中的一些数据类型最终会有很多记录

data MyData
  = A Int Int String Float Int (Char, Char)
  | B Int String Float (Char, String) String

为了检查它是什么类型,我最终编写了类似的函数

isA :: MyData -> Bool
isA (A _ _ _ _ _ _) = True
isA _ = False

-- isB and so on

现在这很快就会变得很麻烦,所以我搜索了如何使用derive 或类似于自动生成这些的东西,然后我找到了this。但是,由于引入了ghc generics 和相关的generic-deriving library,该问题中提出的library 似乎已经过时。我看过这些,但它们似乎非常强大,我不知道从哪里开始。

所以我的问题是:您如何(如果可能)避免为MyData 手动编写isAisB

【问题讨论】:

  • 相关 Reddit 线程:reddit.com/r/haskell/comments/74r611/deriving_is_functions。虽然……我不确定这些会使你已经发现的图书馆过时吗?
  • 它的构建状态为“失败”的事实以及其下方的评论。也许说它“过时”是不准确的,我不确定。
  • 如果你这样写会有帮助吗:data MyData = A (Int, Int, String, Float, Int, (Char, Char)) | B (Int, String, Float, (Char, String), String)?
  • 切题:虽然这是一个完全合理的问题,但您可能需要仔细检查您是否需要以及多久实际需要布尔测试。例如,if isA x -- etc. 检查通常可以替换为x 上的模式匹配(例如,使用case 表达式)。

标签: haskell


【解决方案1】:

可以利用记录语法来实现这一点。

isA :: MyData -> Bool
isA A{} = True
isA _   = False

这不需要扩展,并且无论构造函数 A 需要多少参数都可以工作。

(话虽如此,我认为这些函数在 Haskell 中没有那么有用。当心“布尔盲”——即在不需要时将信息简化为布尔值。)

【讨论】:

  • 好的,那么也许我会尽量避免这种情况,感谢您的澄清。
【解决方案2】:

因此,一种避免盲目编写大量类型检查函数的方法是使用 this library(在 Reddit 中找到 Ry 发布 - 谢谢!)。

示例代码:

import Data.Generics.Is.TH

-- Cumbersome
printType (A _ _ _ _ _ _) = putStrLn "Is A"
printType (B _ _ _ _ _) = putStrLn "Is B"

-- With library
printType x
  | $(is 'A) x = putStrLn "Is A"
  | $(is 'B) x = putStrLn "Is B"

您只需写 $(is 'A)$(is 'B) 而不是 isAisB,这对我来说很好。

【讨论】:

  • 这比使用你原来的isA :: MyData -> Bool函数有什么好处?
  • 2 个优点:首先,您不需要为每种类型(A、B 等等)手动定义一个函数,其次,当您稍后添加/删除某个类型的记录时,您就赢了'不需要在相应的类型检查函数中添加/删除“_”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
相关资源
最近更新 更多