创建一个以字符串形式描述其数据类型名称的值

时间:2013-12-20 21:57:00

标签: haskell

是否可以在Haskell中创建一个数据类型名称被描述为字符串的值?它类似于Java中newInstance类的Class方法。

这是一个例子。假设数据:

data Person = Person {name::String}

我想创建一个类似于此的Person值:

let myPerson = create "Person"

,其中create函数创建的值为Pearsonname字段为空。

我希望create函数可以对任何数据执行此操作。所以,我不想要一些静态的东西。

这可能吗?

1 个答案:

答案 0 :(得分:1)

松散地说,是的:

{-# LANGUAGE DeriveDataTypeable #-}

import Data.Dynamic

data Person = Person { personName :: String }
  deriving (Show, Typeable)

data Cat = Cat { catName :: String }
  deriving (Show, Typeable)

create :: String -> Dynamic
create "Person" = toDyn Person { personName = "" }
create "Cat" = toDyn Cat { catName = "" }
create other = error $ "Cannot create " ++ other

main :: IO ()
main = do
  let myPerson = (create "Person") { personName = "Bill" }
  print (fromDynamic myPerson)

您还可以使用Data.Default来默认所有字段,以便获得合理的价值。但是用一组不相关的类型做这个似乎是个坏主意。如果您使用ADT的不同构造函数进行操作,那么您所获得的是该数据类型的解析器的基础,该解析器仅解析构造函数。例如:

data Housemate
  = Person { name :: String }
  | Cat { name :: String }
  | Dog { name :: String }

create :: String -> String -> Housemate  -- No longer dynamic.
create "Person" = Person
create "Cat" = Cat
create "Dog" = Dog

但是你可能想采取不同的方法。 Haskell与动态类型不兼容。如果您提供有关您尝试解决的实际问题的更多信息,您将获得更好的答案。