fork download
  1. {-# LANGUAGE DataKinds, KindSignatures, TypeFamilies, GADTs #-}
  2.  
  3. import Control.Applicative
  4.  
  5. -- | Type-level naturals
  6. data Nat = Z | S Nat
  7.  
  8. -- | Type family for n-ary functions
  9. type family Fn (n :: Nat) a b
  10. type instance Fn Z a b = b
  11. type instance Fn (S n) a b = a -> Fn n a b
  12.  
  13. -- | Lists exposing their length in their type
  14. data List a (n :: Nat) where
  15. Nil :: List a Z
  16. Cons :: a -> List a n -> List a (S n)
  17.  
  18. -- | General <*> applied to a list of arguments of the right length
  19. class Apply (n :: Nat) where
  20. foldF :: Applicative f => f (Fn n a b) -> List (f a) n -> f b
  21.  
  22. instance Apply Z where
  23. foldF f0 Nil = f0
  24.  
  25. instance Apply n => Apply (S n) where
  26. foldF fn (Cons x xs) = foldF (fn <*> x) xs
  27.  
  28. -- test :: [(Integer,Integer,Integer)]
  29. test :: [(Integer,Integer,Int)]
  30. test = foldF (pure (,,)) (Cons [10,11] (Cons [20,21] (Cons [30,31] Nil)))
  31. -- Result: [(10,20,30),(10,20,31),(10,21,30),(10,21,31)
  32. -- ,(11,20,30),(11,20,31),(11,21,30),(11,21,31)]
  33. {-
  34. prog.hs:30:15:
  35.   Couldn't match type `Integer' with `Int'
  36.   Expected type: [Fn
  37.   ('S ('S ('S 'Z))) Integer (Integer, Integer, Int)]
  38.   Actual type: [Integer
  39.   -> Integer -> Integer -> (Integer, Integer, Integer)]
  40.   In the return type of a call of `pure'
  41.   In the first argument of `foldF', namely `(pure (,,))'
  42.   In the expression:
  43.   foldF
  44.   (pure (,,)) (Cons [10, 11] (Cons [20, 21] (Cons [30, 31] Nil)))
  45. -}
  46.  
  47. main = print test
  48.  
  49. main2 = print $ zipWith3 (,,) [10,11] ([20,21]::[Integer]) ([30,31]::[Int])
Compilation error #stdin compilation error #stdout 0.01s 6232KB
stdin
Standard input is empty
compilation info
[1 of 1] Compiling Main             ( prog.hs, prog.o )

prog.hs:30:15:
    Couldn't match type `Integer' with `Int'
    Expected type: [Fn
                      ('S ('S ('S 'Z))) Integer (Integer, Integer, Int)]
      Actual type: [Integer
                    -> Integer -> Integer -> (Integer, Integer, Integer)]
    In the return type of a call of `pure'
    In the first argument of `foldF', namely `(pure (,,))'
    In the expression:
      foldF
        (pure (,,)) (Cons [10, 11] (Cons [20, 21] (Cons [30, 31] Nil)))
stdout
Standard output is empty