【发布时间】:2014-02-12 07:56:18
【问题描述】:
我有这个代码
data Container = Box Int | Bag Int
inBox :: [Container] -> Int
inBox [] = 0
inBox (x:ls) | (Box i) <- x = i + inBox ls
| otherwise = inBox ls
inBag :: [Container] -> Int
inBag [] = 0
inBag (x:ls) | (Bag i) <- x = i + inBag ls
| otherwise = inBag ls
显然InBox 和InBag 具有相同的结构。我想制作一个包含它们的功能。我不知道如何将构造函数(Box 或Bag)作为参数传递。
理想情况下,通用函数应如下所示:
inSome :: Constructor -> [Container] -> Int
inSome con [] = 0
inSome con (x:ls) | (con i) <- x = i + inSome con ls
| otherwise = inSome con ls
显然这不起作用,因为构造函数不是这里定义的类型。我该怎么做?
一个想法是像这样将它作为函数传递:
inSome :: (Int -> Container) -> [Container] -> Int
inSome _ [] = 0
inSome con (x:ls) | (con i) <- x = i + inSome ls
| otherwise = inSome ls
然后我得到错误:
模式中的解析错误:con
因为它无法匹配这样的功能。
我想这样做的原因是因为我有一个复杂的数据类型,其中包括二进制操作(例如 +、#、:: 等...)我有几个函数对于这些构造函数几乎相同。我不想把它们都写下来,然后一起修改。我必须有一种方法可以在函数中做到这一点。也许有人可以在 cmets 中提出另一种方法?
【问题讨论】:
-
你为什么要这样做?
-
定义
unContainer :: (Int->a)->(Int->a)->Container->a,然后定义inBox (x:ls) = unContainer (+(inBox ls)) (const (inBox ls)) x,和inBag相同,但交换unContainer参数。如果你愿意,你可以概括更多,所以实际上 inBox 和 inBag 会相差flip,但在这种特殊情况下,我不明白你为什么要这样做。 -
已编辑以解释我为什么要这样做,希望对您有所帮助。
标签: haskell constructor