如何使用MonadWriter约束创建一个类型类实例?

时间:2017-01-28 11:45:24

标签: haskell

{-# 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不是我想要的。

在上一版本中,我使用了一个编写器实例,但我不确定如何使用MonadWriterMonadState约束使其更通用。我已经尝试在StatementsParser newtype中添加类型类约束,但这也不起作用。

现在我在想,也许在课堂宣传期间需要加入约束,但这并不会让我受到影响。

这有点令人困惑。

1)如何在实例声明中加入更复杂的类型类约束?

2)类型类约束可以进入newtype声明吗?

3)代替使用代码片段中的newtype,可以使用类型synonim代替,这样我就不必进行打包和解包了吗?

0 个答案:

没有答案