【问题标题】:Can I build a list of Strings using each constructor of a class?我可以使用类的每个构造函数构建字符串列表吗?
【发布时间】:2017-06-07 18:44:52
【问题描述】:

我有一个简单的数据类型,例如:

data Class = Class1
           | Class2
           | Class3
           deriving (Show, Eq)

我有没有一种简单的方法来构建一个字符串列表,其中包含每个字符串的字符串版本,例如:

func Class = ["Class1", "Class2", "Class3"]

【问题讨论】:

  • 排序...func 的类型是什么?

标签: list haskell types


【解决方案1】:

答案是肯定的,但有一点需要注意。 func 的类型是什么?看起来它的第一个参数是一个类型,而不是一个值。稍后再说……


派生Enum 使您能够列出连续的构造函数,而派生Bounded 使您能够获取此枚举的“第一个”和“最后一个”元素。

data Class = Class1
           | Class2
           | Class3
           deriving (Show, Eq, Enum, Bounded)

然后,我们可以通过enumFromTo minBound maxBound(或只是[minBound .. maxBound])获取所有元素的列表。

但是,回到关于func 类型的最初问题。您需要传入一个类型作为参数。通常的做法是使用ProxyScopedTypeVariables

{-# LANGUAGE ScopedTypeVariables #-}

import Data.Proxy (Proxy(..))

func :: forall a. (Enum a, Bounded a, Show a) => Proxy a -> [String]
func Proxy = map show $ enumFromTo minBound (maxBound :: a)

在 GHCi 试试这个:

ghci> func (Proxy :: Proxy Class)
["Class1","Class2","Class3"]
ghci> func (Proxy :: Proxy Bool)
["True","False"]

【讨论】:

  • 虽然您的答案是更多的教育,也许更完整,但我接受另一个只是因为它更简单地满足了我的需求。不过感谢您的回复!
  • 我认为其他答案不满足问题中设置的条件。如果您已经可以使用“Class1”,为什么不使用所有其他的呢?
  • @karakfa 您的评论是否可能用于其他答案?我不明白它在这里是如何应用的......
  • 这个比我的回答好很多,所以我要删了(我的回答,就是这样)。
  • @MarkSeemann 我会接受 Alec 的回答,因为您认为它会更好,但我认为值得留给后代。
【解决方案2】:

也许你可以这样做:

data Class = Class1 | Class2 | Class3 deriving (Show, Eq, Enum)

GHCI:

Prelude> fmap show $ enumFrom Class1
["Class1","Class2","Class3"]

【讨论】:

  • 这正是我想要的!谢谢!
  • @FutureShocked 我认为亚历克的回答要好得多。你应该接受它而不是我的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-21
  • 2010-11-23
  • 2014-04-15
  • 2014-05-22
相关资源
最近更新 更多