访问 monad 内的 haskell 中记录的值的优雅方法

Nai*_*dra 1 monads haskell functional-programming record pointfree

问题的概括(请阅读下文以了解我当前问题的具体情况)

给定函数类型定义:自定义数据类型在f :: MonadIO m -> a -> m B哪里,我如何访问成员,例如从返回的值访问成员?BB = B {x y z ...}xf

问题

我正在尝试使用wave包来制作应用程序,但我有一个简单的问题:我希望访问waveFileFormat数据类型Wave

然而,简单地这样做waveFileFormat $ readWaveFile "file"是行不通的,因为readWaveFile "file"实际上是readWaveFileMonadIO m => m Wave返回的。

我尝试过但不起作用

readWaveFile "file" >>= waveFileFormat readWaveFile "file" >> waveFileFormat

什么有效(但看起来不优雅并且非常渴望它是什么)

do{wave<-readWaveFile "file"; return $ waveFileFormat wave}


然而,由于赋值,这种方法在“do”块之外不起作用。它也非常长并且像样板文件。我怎样才能避免这种情况?

luq*_*qui 6

您可以使用fmap(或其中缀运算符形式,(<$>)):

waveFileFormat <$> readWaveFile "file"
Run Code Online (Sandbox Code Playgroud)

这有类型MonadIO m => m WaveFormat。你永远无法逃脱单子,但你可以继续随心所欲地操纵它的价值。

  • “*你永远无法逃脱单子*” - 这取决于单子。当然,“MonadIO”单子使这变得困难,因为你无法转义“IO”单子(没有“unsafePerformIO”),但对于其他单子类型通常是可能的。(不确定OP的问题有多普遍) (4认同)
  • @NaitikMundra,所有单子也是函子。另外,该页面上的答案......嗯......错误。 (4认同)
  • @Bergi你永远无法逃脱单子_多态_。 (2认同)