【问题标题】:Accessing values in haskell custom data type访问 haskell 自定义数据类型中的值
【发布时间】:2018-01-03 20:33:16
【问题描述】:

我是 haskell 的新手,需要使用特定的数据类型来解决我正在处理的问题。

data Tree a = Leaf a | Node [Tree a]
deriving (Show, Eq)

所以当我创建一个实例时,例如 Node[Leaf 1, Leaf2, Leaf 3] 我如何访问这些?它不会让我使用 head 或 tail 或 indexing with !! .

【问题讨论】:

  • 关于术语的注释。您定义的是一个“类型构造函数”(Tree),它可以提供一个类型参数来生成一个类型(例如Tree Int)和几个“数据构造函数”(LeafNode)可以提供值参数来产生一个值(不是“实例”)。例如,请参阅this prior question and answer
  • 这很好,因为应该尽可能避免使用像 head,tail,!! 这样的部分函数,​​而是使用模式匹配。

标签: haskell


【解决方案1】:

您执行模式匹配。例如,如果您想要第一个孩子,您可以使用:

firstChild :: Tree a -> Maybe (Tree a)
firstChild (Node (h:_)) = Just h
firstChild _ = Nothing

这里我们将答案包装在 Maybe 类型中,因为我们可能会处理 Leaf xNode [],这样就没有第一个孩子。

或者我们可以例如获得第 i 项:

iThChild :: Int -> Tree a -> Tree a
iThChild i (Node cs) = cs !! i

所以这里我们解开Node构造函数,得到子列表cs,然后执行cs !! i得到i-th子。但是请注意,(!!) :: [a] -> Int -> a 通常是一种反模式:它是不安全的,因为我们不能保证列表包含足够的元素,并且使用 length 也是一种反模式,因为列表可以有无限长,所以我们不能做这样的边界检查。

通常,如果一个人在 Haskell 中编写算法,则倾向于利用 linear 访问,并编写 total 函数:总是返回一些东西的函数。

【讨论】:

  • 线性访问是什么意思?
猜你喜欢
  • 2014-08-05
  • 1970-01-01
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多