假設我有一個元組,如('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()',它不接受任何參數並返回輸出,並且沒有重疊的危險。 –