I am trying to write a bunch of statements with Hspec inside a single polysemy's Sem
Monad as such:
{-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module StorageSpec (main, spec) where
import Test.Hspec
import Storage
import Data.Aeson
import Data.Maybe(fromJust)
import qualified Data.Text as T
import qualified Database.Bloodhound as B
import qualified Database.Bloodhound.Types as B
import GHC.Generics
import Polysemy (Embed, Member, Sem, makeSem, embed, interpret, reinterpret)
import Polysemy.IO
import Polysemy.State
data Storage (d :: *) (m :: * -> *) (a :: *) where
CreateContainer :: B.IndexName -> B.IndexSettings -> Storage d m Bool
makeSem ''Storage
scenarii :: Member (Storage Book) r => Sem r (SpecWith ())
scenarii = do
indexCreation <- it "create index should work the first time" . flip shouldBe True
<$> (createContainer exampleIndex exampleMapping :: Member (Storage Book) r => Sem r Bool)
return $ indexCreation
data Book = Book { name :: String, entries :: Int } deriving (Eq, Show, Generic, FromJSON, ToJSON)
While specifying explicitly the Storage Book
Member
I have the following error:
• Ambiguous use of effect 'Storage'
Possible fix:
add (Member (Storage d1) r1) to the context of
the type signature
If you already have the constraint you want, instead
add a type application to specify
'd1' directly, or activate polysemy-plugin which
can usually infer the type correctly.
• In the second argument of ‘(<$>)’, namely
‘(createContainer exampleIndex exampleMapping ::
Member (Storage Book) r => Sem r Bool)’
In a stmt of a 'do' block:
indexCreation <- it "create index should work the first time"
. flip shouldBe True
<$>
(createContainer exampleIndex exampleMapping ::
Member (Storage Book) r => Sem r Bool)
In the expression:
do indexCreation <- it "create index should work the first time"
. flip shouldBe True
<$>
(createContainer exampleIndex exampleMapping ::
Member (Storage Book) r => Sem r Bool)
return $ indexCreation
|
39 | <$> (createContainer exampleIndex exampleMapping :: Member (Storage Book) r => Sem r Bool)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I do not see what can I do to help the type-checker.
It occurs that
d
acts as a Phantom type in case ofCreateContainer
, in order to fix it I had to use type application: