Haskell记录函数约束

时间:2016-10-18 10:23:02

标签: haskell

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)

它不起作用,因为我不能对记录功能有约束,但它看起来也很难看,所以我很确定应该有更好的方法来做它。

1 个答案:

答案 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)