Haskell表达的方式是什么:
data SinkBuilder
{ openSink :: MonadIO m => m Sink
}
data Sink = Sink
{ writeSink :: MonadIO m => Value -> m ()
, closeSink :: MonadIO m => m ()
}
我想我需要的是一组在数据类型中方便地“捆绑”在一起的函数,因此这个数据类型被创建并作为一个整体传递?
这对于组合原因似乎很有用,例如,我可以实现像
这样的东西(:+:) :: SinkBuilder -> SinkBuilder -> SinkBuilder
a :+: b = SinkBuilder $ do
sa <- openSink a
sb <- openSink b
return $ Sink (\v -> writeSink sa >> writeSink sb) (closeSink sa >> closeSink sb)
它不起作用,因为我不能对记录功能有约束,但它看起来也很难看,所以我很确定应该有更好的方法来做它。
答案 0 :(得分:0)
这编译,但我不清楚你真正想做什么。我担心这不是你想要的。
{-# LANGUAGE ScopedTypeVariables, RankNTypes #-}
import Control.Monad.Trans
type Value = Int
data SinkBuilder = SB
{ openSink :: forall m. MonadIO m => m Sink
}
data Sink = Sink
{ writeSink :: forall m. MonadIO m => Value -> m ()
, closeSink :: forall m. MonadIO m => m ()
}
(#+#) :: SinkBuilder -> SinkBuilder -> SinkBuilder
a #+# b = SB $ do
sa <- openSink a
sb <- openSink b
return $ Sink (\v -> writeSink sa v >> writeSink sb v) (closeSink sa >> closeSink sb)