假设我有一个元组,如('a',(1,("Hello",False))
。为了好玩(阅读:学习),我想创建一个函数,将正确形式的一些函数应用于任何这样的元组并返回结果。用法示例:Haskell:将函数应用于嵌套2元组的函数
applyFnToTuple ('o',('t','w')) $ \a b c -> [a,b,c] == "otw"
applyFnToTuple ('h','i') $ \a b -> [a,b] == "hi"
applyFnToTuple ("hello",('y','o')) $ \a b c -> a ++ [b,c]
我所做的大部分如下:
type family TupleFn ty out where
TupleFn (a,b) output = a -> (TupleFn b output)
TupleFn b output = b -> output
class ApplyFnToTuple a where
applyFnToTuple :: a -> TupleFn a out -> out
instance ApplyFnToTuple b => ApplyFnToTuple (a,b) where
applyFnToTuple (a,b) fn = applyFnToTuple b (fn a)
instance ApplyFnToTuple a where
applyFnToTuple b fn = fn b
的症结是,最后一个实例。我完全预计需要添加{-# OVERLAPPABLE #-}
,因为a
比(a,b)
更普遍。我也很难确切地知道GHC如何解决a
和我的TupleFn
类的正确版本,并且知道正确的类型信号,但是我可以很容易地把它归结为我自己的缺乏理解。但在任何情况下,实际误差GHCI给我的是:
Couldn't match expected type ‘a -> out’
with actual type ‘TupleFn a out’
Relevant bindings include
fn :: TupleFn a out (bound at examples.hs:574:22)
b :: a (bound at examples.hs:574:20)
applyFnToTuple :: a -> TupleFn a out -> out
(bound at examples.hs:574:5)
The function ‘fn’ is applied to one argument,
but its type ‘TupleFn a out’ has none
In the expression: fn b
In an equation for ‘applyFnToTuple’: applyFnToTuple b fn = fn b
Failed, modules loaded: none.
据我所看到的,没有版本我TupleFn的返回的东西不带任何参数,所以我真的不理解的错误。不过,我觉得它可以做出改变的最后一个实例,以更具体的东西如简单地编译:
instance ApplyFnToTuple Char where
applyFnToTuple b fn = fn b
但这意味着我不得不定义许多类似的情况等,这是不可取的。
我想知道的是,是否有一个相对简单的方法来使更普通的版本工作,以及为什么这个特定的错误?
三江源:)
PS:我运行GHC 7.10.1
相关:[如何创建大多数泛型函数可能将函数应用于元组项目](http://stackoverflow.com/questions/31220903/haskell-how-to-create-most-generic-function-possible-这是应用功能) – Cirdec
这是我的另一个问题。它涉及到一个元组,但并不真正相关☺ – jsdw
建议:使用'(a,(b,(c,())))'来代替'(a,(b,c))'。然后很容易编写实例'ApplyFnToTuple()',它不接受任何参数并返回输出,并且没有重叠的危险。 –