{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
module Main where
import Control.Monad.Writer hiding ((>>))
import qualified Prelude as P
import Data.String (fromString)
import qualified Data.ByteString.Char8 as B
import Data.ByteString.Char8 (ByteString)
import Prelude hiding ((+),(-),(*),(/),(<=),(<),(==),(>),(>=),negate,exp,log,tanh)
infixl 1 |>
(|>) = flip ($)
newtype Method args = Method {method' :: (ByteString, args)}
class CudaOuter repr where
include :: ByteString -> repr ()
externCBlock :: repr () -> repr ()
method :: ByteString -> repr (ins -> outs) -> repr (Method (ins -> outs))
data Statements =
Statement ByteString
| Indent
| Dedent
deriving Show
quote x = ["\"",x,"\""] |> B.concat
-- type StatementsParser = Writer [Statements] -- Ok
-- type StatementsParser = MonadWriter [Statements] m => m -- Error
newtype StatementsParser m x = StatementsParser {st :: m x}
instance MonadWriter [Statements] m => CudaOuter (StatementsParser m) where
include x = [quote x |> Statement] |> tell |> StatementsParser
--- The outer level of the Cuda compiler language.
cuda_kernel_module kernel_name method_body_macro = do
include "thrust/tuple.h"
include "thrust/functional.h"
include "cub/cub.cuh"
externCBlock $ do
method kernel_name method_body_macro
return ()
main = print "Hello"
The code above gives me this error.
* The constraint `MonadWriter [Statements] m'
is no smaller than the instance head
(Use UndecidableInstances to permit this)
* In the instance declaration for `CudaOuter (StatementsParser m)'
I am not sure what the error means, but am decently sure that UndecidableInstances
is not what I want here.
In the previous version of this, I used a writer instance, but I am not sure how to make it more generic with MonadWriter
and MonadState
constraints. I've tried putting typeclass constraints inside the StatementsParser
newtype, but that did not work either.
Right now I am thinking that maybe the constraints need to be put in during class declaration, but that does not strike me as it either.
This is a bit confusing.
1) How can more complex typeclass constraints be put in during instance declaration?
2) Can typeclass constraints go into newtype declarations?
3) Instead of using a newtype as in the code fragment, can a type synonim be used instead so I do not have to do packing and unpacking?