{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}
import GHC.TypeLits
data N = Z | S N
type family ArgsC a b t where ArgsC a b (a -> x) = S (ArgsC a b x) ArgsC a b b = Z ArgsC _ _ _ = TypeError (Text "error")
type family MakeF a b n where MakeF a b Z = b MakeF a b (S n) = a -> MakeF a b n
class F n where f :: [a] -> MakeF a b n -> b
instance F Z where f [] h = h f _ _ = error "invalid length"
instance F n => F (S n) where f (x : xs) h = f @n xs (h x) f _ _ = error "invalid length"
f' :: forall n a b t. (n ~ ArgsC a b t, t ~ MakeF a b n, F n) => [a] -> t -> b f' = f @n
main = do let xs :: [Int] = [1, 2, 3] let h :: Int -> Int -> Int -> String = \a b c -> show (a + b + c) putStrLn (f' xs h)
вроде не сработает как раз потому, что b тоже может быть функцией a -> b, а нет констрейнта на то, что b это точно не функция, будет ошибка фандепов у инстанса
вроде не сработает как раз потому, что b тоже может быть функцией a -> b, а нет констрейнта на то, что b это точно не функция, будет ошибка фандепов у инстанса