Skip to content

Instantly share code, notes, and snippets.

@robkuz
Last active April 25, 2016 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robkuz/e37a13f47ac653a3dc6974c78d706f9f to your computer and use it in GitHub Desktop.
Save robkuz/e37a13f47ac653a3dc6974c78d706f9f to your computer and use it in GitHub Desktop.
Fun with Aff

I understand what get1 does and that is fine

get1 = attempt $ Affjax.get "http://www.google.com"

I think I know what liftAff does BUT the compiler knows better a

get2 = liftAff $ attempt $ Affjax.get "http://www.google.com"

and gives the following the error message

61  get2 = liftAff $ attempt $ Affjax.get "http://www.google.com"
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

No type class instance was found for

Control.Monad.Aff.Class.MonadAff ( ajax :: AJAX
                                 | _0
                                 )
                                 _1

The instance head contains unknown type variables. Consider adding a type annotation.

in value declaration get2

where _1 is an unknown type
    _0 is an unknown type

Which leaves me scratching my head. Lets assume that the get "http://somesite.com" will return a String.

@hdgarrood
Copy link

The problem is that the compiler doesn't know which monad you're trying to lift into with liftAff; the return type of Affjax.get isn't the issue here. What version of the compiler are you using? I think that this error will just go away if you update to one of the more recent versions which includes constraint inference.

@robkuz
Copy link
Author

robkuz commented Apr 25, 2016

its the latest 0.8.5

@robkuz
Copy link
Author

robkuz commented Apr 25, 2016

 module Main where

 import Prelude

 import Data.Maybe
 import Data.Either

 import Control.Monad.Eff.Console (CONSOLE(), log)
 import Control.Monad.Aff.Class
 import Control.Monad.Aff (launchAff, attempt)

 import Node.Express.App
 import Node.Express.Handler
 import Node.Express.Response

 import Network.HTTP.Affjax as Affjax

handler = do
    send "Foo"

get1 = attempt $ Affjax.get "http://www.google.com"
get2 :: forall e a m. (MonadAff (ajax :: Affjax.AJAX | e) m, Respondable a) => m (Either Error a)
get2 = liftAff $ attempt $ Affjax.get "http://www.google.com"

appSetup = do
    get "/handler/" handler

main = do
     listenHttp appSetup 8080 \_ -> log $ "Listening on 8080"

This gives me

  22  get2 :: forall e a m. (MonadAff (ajax :: Affjax.AJAX | e) m, Respondable a) => m (Either Error a)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Unknown type Error

@robkuz
Copy link
Author

robkuz commented Apr 25, 2016

at some later stage the handlershould look something like this

handler = do
     r <- get2
     send $ show r.response  -- as r is an Either it should be unpacked first

@robkuz
Copy link
Author

robkuz commented Apr 25, 2016

not there yet

25  get2 = liftAff $ attempt $ Affjax.get "http://www.google.com"
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  Could not match type

    { status :: StatusCode
    , headers :: Array ResponseHeader
    , response :: _0
    }

  with type

    a1

  while trying to match type Either Error
                               { status :: StatusCode
                               , headers :: Array ResponseHeader
                               , response :: _0
                               }
    with type Either Error a1
  while checking that expression (($) liftAff) ((($) attempt) (get "http://www.google.com"))
    has type m0 (Either Error a1)
  in value declaration get2

  where m0 is a rigid type variable
          bound at line 25, column 1 - line 28, column 1
        a1 is a rigid type variable
          bound at line 25, column 1 - line 28, column 1
        _0 is an unknown type

           Src   Lib   All
Warnings   12    0     12
Errors     1     0     1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment