Lil*_*ily 6 haskell function currying polyvariadic
所以,我正在尝试实现这里描述的多变量ZipWithN .不幸的是,Paczesiowa的代码似乎是用ghc和HList的过时版本编译的,所以在试图理解它如何工作的过程中,我也将它移植到这两个版本的最新版本(ghc- 7.8.3和此时的HList-0.3.4.1).这很有趣.
无论如何,在中间函数的定义中,我遇到了谷歌没有帮助我修复一次的错误curryN'.在概念上,curryN'很简单:它采用类型级自然数N(或严格来说,该类型的值),以及f第一个参数是长度为HList的函数N,并返回一个N带有HList的-ary函数超出其第一个N参数,并将返回f应用于该HList.它是curry,但是多变量.
它使用三个辅助函数/类:
第一个是ResultType/ resultType,正如我在这里定义的那样. resultType将单个函数作为参数,并在将该函数应用于所需的参数之后返回该函数的类型.(严格地说,它再次返回该类型的未定义值).
例如:
ghci> :t resultType (++)
resultType (++) :: [a]
ghci> :t resultType negate
resultType negate :: (ResultType a result, Num a) => result
Run Code Online (Sandbox Code Playgroud)
(后一种情况,因为如果a恰好是类型的函数x -> y,则resultType必须返回y.因此它不适用于多态函数.)
后两个是和Eat/ eat和MComp/ mcomp,一起定义(连同curryN')在一个文件中(连同破碎curryN')像这样.
eat第一个参数是一个类型为自然数的值N,并返回一个接受N参数并将它们组合成HList的函数:
ghci> :t eat (hSucc (hSucc hZero))
eat (hSucc (hSucc hZero)) :: x -> x1 -> HList '[x, x1]
ghci> eat (hSucc (hSucc hZero)) 5 "2"
H[5, "2"]
Run Code Online (Sandbox Code Playgroud)
据我所知,它完美无缺. mcomp是一种多变量组合函数.它有两个功能,f并且g,在f需要的参数一些数量N.它返回一个函数,N参数,适用f于所有的人,然后应用g到f.(功能顺序(>>>)不止于此(.))
ghci> :t (,,) `mcomp` show
(,,) `mcomp` show :: (Show c, Show b, Show a) => a -> b -> c -> [Char]
ghci> ((,,) `mcomp` show) 4 "str" 'c'
"(4,\"str\",'c')"
Run Code Online (Sandbox Code Playgroud)
比如resultType,它在返回类型为类型变量的函数上"中断",但由于我只计划使用它eat(它的最终返回类型只是一个HList),它应该有效(Paczesiowa似乎这样认为,至少).它确实如果第一个参数eat是固定的:
\f -> eat (hSucc (hSucc hZero)) `mcomp` f
Run Code Online (Sandbox Code Playgroud)
工作良好.
curryN' 但是,定义如下:
curryN' n f = eat n `mcomp` f
Run Code Online (Sandbox Code Playgroud)
但是,尝试将其加载到ghci中会出现此错误:
Part3.hs:51:1:
Could not deduce (Eat n '[] f0)
arising from the ambiguity check for ‘curryN'’
from the context (Eat n '[] f,
MComp f cp d result,
ResultType f cp)
bound by the inferred type for ‘curryN'’:
(Eat n '[] f, MComp f cp d result, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
at Part3.hs:51:1-29
The type variable ‘f0’ is ambiguous
When checking that ‘curryN'’
has the inferred type ‘forall f cp d result (n :: HNat).
(Eat n '[] f, MComp f cp d result, ResultType f cp) =>
Proxy n -> (cp -> d) -> result’
Probable cause: the inferred type is ambiguous
Failed, modules loaded: Part1.
Run Code Online (Sandbox Code Playgroud)
如此清楚eat,mcomp不要像我希望的那样好好地一起玩.顺便提一下,这与mcomp (+) (+1)给出的错误类型有很大不同,后者抱怨重叠实例MComp.
无论如何,试图找到关于这个错误的信息并没有把我带到任何有用的东西 - 我自己调试的最大障碍是我不知道类型变量f0是什么,因为它没有出现在任何类型中签名或上下文ghci推断.
我最好的猜测是,mcomp在通过eat多态返回类型递归时遇到了麻烦(即使这是由类型级自然数修复的).但如果是这样的话,我不知道如何修复它.
此外(和奇怪的是我),如果我尝试结合起来Part1.hs,并Part2.hs成一个单一的文件,我还得到一个错误......但一个不同
Part3alt.hs:59:12:
Overlapping instances for ResultType f0 cp
arising from the ambiguity check for ‘curryN'’
Matching givens (or their superclasses):
(ResultType f cp)
bound by the type signature for
curryN' :: (MComp f cp d result, Eat n '[] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
at Part3alt.hs:(59,12)-(60,41)
Matching instances:
instance result ~ x => ResultType x result
-- Defined at Part3alt.hs:19:10
instance ResultType y result => ResultType (x -> y) result
-- Defined at Part3alt.hs:22:10
(The choice depends on the instantiation of ‘cp, f0’)
In the ambiguity check for:
forall (n :: HNat) cp d result f.
(MComp f cp d result, Eat n '[] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for ‘curryN'’:
curryN' :: (MComp f cp d result, Eat n [] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)
再次与神秘的f0类型变量.我承认我在这里有一点点类型的东西,所以如果有人能帮我弄清楚这里究竟是什么问题,更重要的是,我如何解决它(如果是的话,希望,可能),我将非常感激.
最后注意:这里的两个文件称为Part1和Part3的原因是Part2包含一些辅助函数zipWithN,但不是curryN'.在大多数情况下,他们的工作正常,但我可能会在稍后提出一些奇怪的问题.
| 归档时间: |
|
| 查看次数: |
182 次 |
| 最近记录: |