Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何将值列表转换为数据构造函数';s参数?_Haskell - Fatal编程技术网

Haskell 如何将值列表转换为数据构造函数';s参数?

Haskell 如何将值列表转换为数据构造函数';s参数?,haskell,Haskell,我正在处理一个web请求,并试图保存一个潜在的实体(用户/地址1)。主要的问题是,如何将字符串列表转换为参数,并将其转换为函数,其中列表可以是任意长度的 我已经看过了,但这似乎是一个解决方案,只有在事先知道参数的数量 我正在寻找一个大致如下的函数: f :: [String] -> (? -> c) -> Maybe c f fields c = undefined 所以我只需要传递数据构造函数(User/Address1)和字符串列表 示例: f ufields用户将返回

我正在处理一个web请求,并试图保存一个潜在的实体(用户/地址1)。主要的问题是,如何将字符串列表转换为参数,并将其转换为函数,其中列表可以是任意长度的

我已经看过了,但这似乎是一个解决方案,只有在事先知道参数的数量


我正在寻找一个大致如下的函数:

f :: [String] -> (? -> c) -> Maybe c
f fields c = undefined
所以我只需要传递数据构造函数(User/Address1)和字符串列表

示例:

f ufields用户
将返回
Just(用户“chris”“str”)

f[“chris”]用户
将返回
Nothing

f[]用户
将返回
Nothing

f afields Address1
将返回
Just(Address1“earth”)

不使用TemplateHaskell是否可以实现这一点?我可以手动实现上述功能,但需要额外键入大量内容:

data User = User String String deriving (Show)
data Address1 = Address1 String deriving (Show)

data EntityType = UserEntity | AddressEntity
data EntityContainer = UserContainer User | AddressContainer Address1

f :: EntityType -> [String] -> Maybe EntityContainer
f UserEntity  (p:p':[]) = Just $ UserContainer $ User p p'
f AddressEntity  (p:[]) = Just $ AddressContainer $ Address1 p
f _ _ = Nothing

printPossibleEntity :: [String] -> EntityType -> IO ()
printPossibleEntity fields entityType = 
  case (f entityType fields) of
    Just (UserContainer u) -> print u
    Just (AddressContainer a) -> print a
    Nothing -> print "No entity matched"

main :: IO ()
main = do
  let ufields = ["chris", "str"]
  let afields = ["earth"]
  printPossibleEntity ufields UserEntity
  printPossibleEntity afields AddressEntity
  printPossibleEntity [] AddressEntity
哪些产出:

User "chris" "str"
Address1 "earth"
"No entity matched"

让我先说一句,你几乎肯定不应该使用这个

做这类事情的通常方法是使用重叠的多参数类型类

第一次尝试 在这里,它正在发挥作用:

ghci> data User = User String String deriving Show
ghci> data Address1 = Address1 String deriving Show
ghci> packArgs ["chris","str"] User :: Maybe User
Just (User "chris" "str")
ghci> packArgs ["chris"] User :: Maybe User
Nothing
ghci> packArgs [] User :: Maybe User
Nothing
ghci> packArgs ["earth"] Address1 :: Maybe Address1
Just (Address1 "earth")
ghci> data User = User String String deriving Show
ghci> data Address1 = Address1 String deriving Show
ghci> packArgs ["chris","str"] User
Just (User "chris" "str")
ghci> packArgs ["chris"] User
Nothing
ghci> packArgs [] User
Nothing
ghci> packArgs ["earth"] Address1
Just (Address1 "earth")
问题是,我们需要类型注释才能工作。简而言之,Haskell需要知道您的预期回报类型是什么。我们可以用一些类型族来解决这个问题

第二次尝试 在这里,它正在发挥作用:

ghci> data User = User String String deriving Show
ghci> data Address1 = Address1 String deriving Show
ghci> packArgs ["chris","str"] User :: Maybe User
Just (User "chris" "str")
ghci> packArgs ["chris"] User :: Maybe User
Nothing
ghci> packArgs [] User :: Maybe User
Nothing
ghci> packArgs ["earth"] Address1 :: Maybe Address1
Just (Address1 "earth")
ghci> data User = User String String deriving Show
ghci> data Address1 = Address1 String deriving Show
ghci> packArgs ["chris","str"] User
Just (User "chris" "str")
ghci> packArgs ["chris"] User
Nothing
ghci> packArgs [] User
Nothing
ghci> packArgs ["earth"] Address1
Just (Address1 "earth")

为什么需要对构造函数进行抽象?如果您事先不知道其类型,您将如何使用
f
的返回值?我将创建一个typeclass,其中
User
将有一个与此相关的实例。因此,
save(用户“chris”“str”)
可以作为一个例子。这似乎是一个糟糕的设计。与其尝试创建一个完成所有工作的函数,还不如创建几个更小、更简单的函数,每个函数处理不同的实体类型。
ghci> data User = User String String deriving Show
ghci> data Address1 = Address1 String deriving Show
ghci> packArgs ["chris","str"] User
Just (User "chris" "str")
ghci> packArgs ["chris"] User
Nothing
ghci> packArgs [] User
Nothing
ghci> packArgs ["earth"] Address1
Just (Address1 "earth")