====== {-# LANGUAGE FlexibleInstances #-} ====== ~~DISCUSSION~~ * allows to implement instances that are of form (T a1 ... an) where a1 ... an are particlar types (not type variables) * [Double] instead of [a] * implies the application of extension ''[[codesnippets:typesynonyminstances|TypeSynonymInstances]]'' * example: * code: main :: IO () main = do print x1 print x2 class MyClass x where fMy :: x -> x -> x type MySpeed = Double instance MyClass [MySpeed] where fMy xA xB = xA ++ xB data MyData a = C a deriving Show type MySpeedData = (MyData MySpeed) instance MyClass MySpeedData where fMy (C xA) (C xB) = C (xA + xB) x1 :: [MySpeed] x1 = fMy [1.3] [2.5, 3.7] x2 :: MySpeedData x2 = fMy (C 1.3) (C 2.5) * compiler errors: app\Main.hs:12:10: error: * Illegal instance declaration for `MyClass [MySpeed]' (All instance types must be of the form (T a1 ... an) where a1 ... an are *distinct type variables*, and each type variable appears at most once in the instance head. Use FlexibleInstances if you want to disable this.) * In the instance declaration for `MyClass [MySpeed]' | 12 | instance MyClass [MySpeed] where | ^^^^^^^^^^^^^^^^^ app\Main.hs:20:10: error: * Illegal instance declaration for `MyClass MySpeedData' (All instance types must be of the form (T t1 ... tn) where T is not a synonym. Use TypeSynonymInstances if you want to disable this.) * In the instance declaration for `MyClass MySpeedData' | 20 | instance MyClass MySpeedData where | ^^^^^^^^^^^^^^^^^^^ * example: * code: {-# LANGUAGE TypeSynonymInstances #-} main :: IO () main = do print x1 print x2 class MyClass x where fMy :: x -> x -> x type MySpeed = Double instance MyClass [MySpeed] where fMy xA xB = xA ++ xB data MyData a = C a deriving Show type MySpeedData = (MyData MySpeed) instance MyClass MySpeedData where fMy (C xA) (C xB) = C (xA + xB) x1 :: [MySpeed] x1 = fMy [1.3] [2.5, 3.7] x2 :: MySpeedData x2 = fMy (C 1.3) (C 2.5) * compiler errors: app\Main.hs:14:10: error: * Illegal instance declaration for `MyClass [MySpeed]' (All instance types must be of the form (T a1 ... an) where a1 ... an are *distinct type variables*, and each type variable appears at most once in the instance head. Use FlexibleInstances if you want to disable this.) * In the instance declaration for `MyClass [MySpeed]' | 14 | instance MyClass [MySpeed] where | ^^^^^^^^^^^^^^^^^ app\Main.hs:22:10: error: * Illegal instance declaration for `MyClass MySpeedData' (All instance types must be of the form (T a1 ... an) where a1 ... an are *distinct type variables*, and each type variable appears at most once in the instance head. Use FlexibleInstances if you want to disable this.) * In the instance declaration for `MyClass MySpeedData' | 22 | instance MyClass MySpeedData where | ^^^^^^^^^^^^^^^^^^^ * example, with GHC option: * code: {-# LANGUAGE FlexibleInstances #-} main :: IO () main = do print x1 print x2 class MyClass x where fMy :: x -> x -> x type MySpeed = Double instance MyClass [MySpeed] where fMy xA xB = xA ++ xB data MyData a = C a deriving Show type MySpeedData = (MyData MySpeed) instance MyClass MySpeedData where fMy (C xA) (C xB) = C (xA + xB) x1 :: [MySpeed] x1 = fMy [1.3] [2.5, 3.7] x2 :: MySpeedData x2 = fMy (C 1.3) (C 2.5) * compiles, error and warning free, with compiler: GHC 8.10.4, using compiler option -Wall * executes, with output: [1.3,2.5,3.7] C 3.8 ===== ✎ ===== ~~DISCUSSION~~