{-# 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 constraint `MonadWriter [Statements] m'
is no smaller than the instance head
(Use UndecidableInstances to permit this)
* In the instance declaration for `CudaOuter (StatementsParser m)'
我不确定错误的含义,但我确信UndecidableInstances
不是我想要的。
在上一版本中,我使用了一个编写器实例,但我不确定如何使用MonadWriter
和MonadState
约束使其更通用。我已经尝试在StatementsParser
newtype中添加类型类约束,但这也不起作用。
现在我在想,也许在课堂宣传期间需要加入约束,但这并不会让我受到影响。
这有点令人困惑。
1)如何在实例声明中加入更复杂的类型类约束?
2)类型类约束可以进入newtype声明吗?
3)代替使用代码片段中的newtype,可以使用类型synonim代替,这样我就不必进行打包和解包了吗?