【发布时间】:2018-09-02 03:54:29
【问题描述】:
我正在尝试实现primitive recursive functions。显然在 Haskell 中使用可变参数函数并不常见,我使用了一个类型
data PrimT a = Sgl a | Sqc [a]
所以我可以将原子值和值列表传递给函数。这适用于零函数、投影和后继函数:
zero k (Sqc args) = if length args == k then Right 0 else Left "invalid number of arguments"
zero 1 (Sgl arg) = Right 0
pi i k (Sqc args) = if length args == k then Right $ args!!i else Left "invalid number of arguments"
pi 1 1 (Sgl arg) = Right arg
nu (Sgl i) = Sgl $ i + 1
但是我遇到了构图问题(这里是o)。这个定义背后的想法是组合可以发生在函数 f 和:1)函数列表和参数列表,2)函数列表和一个参数,3)一个函数和一个参数列表,最后 4 ) 一个函数和一个参数。因此,我将函数和PrimT 放在了Sqc gs 的函数列表和Sgl g 的单个函数中。参数相同:Sqc args 和 Sgl arg。
o :: PrimT (PrimT b -> PrimT c) -> PrimT (PrimT a -> PrimT b) -> PrimT a -> PrimT c
o (Sgl f) (Sqc gs) (Sqc args) = f [g args | g <- gs]
-- o (Sgl f) (Sqc gs) (Sgl arg) = f [g arg | g <- gs]
-- o (Sgl f) (Sgl g) (Sqc args) = f [g args]
-- o (Sgl f) (Sgl g) (Sgl arg) = f [g arg]
但是编译器对f [g args | g <- gs] 部分不满意。它说:
primrec.hs:69:35: error:
• Couldn't match expected type ‘PrimT b’
with actual type ‘[PrimT b]’
• In the first argument of ‘f’, namely ‘[g args | g <- gs]’
In the expression: f [g args | g <- gs]
In an equation for ‘o’:
o (Sgl f) (Sqc gs) (Sqc args) = f [g args | g <- gs]
• Relevant bindings include
gs :: [PrimT a -> PrimT b] (bound at primrec.hs:69:16)
f :: PrimT b -> PrimT c (bound at primrec.hs:69:8)
o :: PrimT (PrimT b -> PrimT c)
-> PrimT (PrimT a -> PrimT b) -> PrimT a -> PrimT c
(bound at primrec.hs:69:1)
|
69 | o (Sgl f) (Sqc gs) (Sqc args) = f [g args | g <- gs]
| ^^^^^^^^^^^^^^^^^^
primrec.hs:69:38: error:
• Couldn't match expected type ‘PrimT a’ with actual type ‘[a]’
• In the first argument of ‘g’, namely ‘args’
In the expression: g args
In the first argument of ‘f’, namely ‘[g args | g <- gs]’
• Relevant bindings include
g :: PrimT a -> PrimT b (bound at primrec.hs:69:45)
args :: [a] (bound at primrec.hs:69:25)
gs :: [PrimT a -> PrimT b] (bound at primrec.hs:69:16)
o :: PrimT (PrimT b -> PrimT c)
-> PrimT (PrimT a -> PrimT b) -> PrimT a -> PrimT c
(bound at primrec.hs:69:1)
|
69 | o (Sgl f) (Sqc gs) (Sqc args) = f [g args | g <- gs]
|
但我不明白为什么。 PrimT a 根据其定义可以是a ([a]) 的列表。那么问题出在哪里?
【问题讨论】:
-
Just 'x'与'x'不同。Char与Maybe Char的类型不同。 -
如果不进一步解释您所指的内容,则无济于事。
-
fwiw,你遇到了所有这些问题,因为你试图绕过类型系统。单个值与值列表不同。你不能只是互换使用它们。当您通过添加第三种类型来解决此问题时,您现在涉及 三种 类型,而不是两种。
-
@Carl 但是将单例列表用于原子值似乎是错误的。
-
Sgl x和Sqc [x]的语义区别是什么?如果没有,为什么你允许两者?
标签: haskell types algebraic-data-types