fork download
  1. data Json = JsonNumber Integer | JsonArray [Json]
  2.  
  3. class T a where
  4. number :: a Integer
  5. array :: a x -> a [x]
  6.  
  7. data ToJson x = ToJson { runToJson :: x -> Json }
  8. instance T ToJson where
  9. number = ToJson $ \x -> JsonNumber x
  10. array (ToJson c) = ToJson $ \xs -> JsonArray $ map c xs
  11.  
  12. data FromJson x = FromJson { runFromJson :: Json -> x }
  13. instance T FromJson where
  14. number = FromJson $ \(JsonNumber x) -> x
  15. array (FromJson c) = FromJson $ \(JsonArray xs) -> map c xs
  16.  
  17. class A a where
  18. method :: (T i, T o) => i x -> o y -> a x y
  19.  
  20. data Server x y = Server { runServer :: (x -> y) -> Json -> Json }
  21. instance A Server where
  22. method i o = Server $ \f -> runToJson o . f . runFromJson i
  23.  
  24. data Client x y = Client { runClient :: (Json -> Json) -> (x -> y) }
  25. instance A Client where
  26. method i o = Client $ \f -> runFromJson o . f . runToJson i
  27.  
  28. add :: (A a) => a [Integer] Integer
  29. add = method (array number) number
  30.  
  31. main = do
  32. let conn = runServer add (foldl (+) 0)
  33. print $ runClient add conn [1, 2, 3]
  34.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
[1 of 1] Compiling Main             ( prog.hs, prog.o )

prog.hs:22:43: error:
    • Couldn't match type ‘o’ with ‘ToJson’
      ‘o’ is a rigid type variable bound by
        the type signature for:
          method :: forall (i :: * -> *) (o :: * -> *) x y.
                    (T i, T o) =>
                    i x -> o y -> Server x y
        at prog.hs:22:5-10
      Expected type: ToJson y
        Actual type: o y
    • In the first argument of ‘runToJson’, namely ‘o’
      In the first argument of ‘(.)’, namely ‘runToJson o’
      In the expression: runToJson o . f . runFromJson i
    • Relevant bindings include
        o :: o y (bound at prog.hs:22:14)
        method :: i x -> o y -> Server x y (bound at prog.hs:22:5)
   |
22 |     method i o = Server $ \f -> runToJson o . f . runFromJson i
   |                                           ^

prog.hs:22:63: error:
    • Couldn't match type ‘i’ with ‘FromJson’
      ‘i’ is a rigid type variable bound by
        the type signature for:
          method :: forall (i :: * -> *) (o :: * -> *) x y.
                    (T i, T o) =>
                    i x -> o y -> Server x y
        at prog.hs:22:5-10
      Expected type: FromJson x
        Actual type: i x
    • In the first argument of ‘runFromJson’, namely ‘i’
      In the second argument of ‘(.)’, namely ‘runFromJson i’
      In the second argument of ‘(.)’, namely ‘f . runFromJson i’
    • Relevant bindings include
        i :: i x (bound at prog.hs:22:12)
        method :: i x -> o y -> Server x y (bound at prog.hs:22:5)
   |
22 |     method i o = Server $ \f -> runToJson o . f . runFromJson i
   |                                                               ^

prog.hs:26:45: error:
    • Couldn't match type ‘o’ with ‘FromJson’
      ‘o’ is a rigid type variable bound by
        the type signature for:
          method :: forall (i :: * -> *) (o :: * -> *) x y.
                    (T i, T o) =>
                    i x -> o y -> Client x y
        at prog.hs:26:5-10
      Expected type: FromJson y
        Actual type: o y
    • In the first argument of ‘runFromJson’, namely ‘o’
      In the first argument of ‘(.)’, namely ‘runFromJson o’
      In the expression: runFromJson o . f . runToJson i
    • Relevant bindings include
        o :: o y (bound at prog.hs:26:14)
        method :: i x -> o y -> Client x y (bound at prog.hs:26:5)
   |
26 |     method i o = Client $ \f -> runFromJson o . f . runToJson i
   |                                             ^

prog.hs:26:63: error:
    • Couldn't match type ‘i’ with ‘ToJson’
      ‘i’ is a rigid type variable bound by
        the type signature for:
          method :: forall (i :: * -> *) (o :: * -> *) x y.
                    (T i, T o) =>
                    i x -> o y -> Client x y
        at prog.hs:26:5-10
      Expected type: ToJson x
        Actual type: i x
    • In the first argument of ‘runToJson’, namely ‘i’
      In the second argument of ‘(.)’, namely ‘runToJson i’
      In the second argument of ‘(.)’, namely ‘f . runToJson i’
    • Relevant bindings include
        i :: i x (bound at prog.hs:26:12)
        method :: i x -> o y -> Client x y (bound at prog.hs:26:5)
   |
26 |     method i o = Client $ \f -> runFromJson o . f . runToJson i
   |                                                               ^

prog.hs:29:7: error:
    • Could not deduce (T i0) arising from a use of ‘method’
      from the context: A a
        bound by the type signature for:
                   add :: forall (a :: * -> * -> *). A a => a [Integer] Integer
        at prog.hs:28:1-35
      The type variable ‘i0’ is ambiguous
      These potential instances exist:
        instance T FromJson -- Defined at prog.hs:13:10
        instance T ToJson -- Defined at prog.hs:8:10
    • In the expression: method (array number) number
      In an equation for ‘add’: add = method (array number) number
   |
29 | add = method (array number) number
   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdout
Standard output is empty