如何在这种情况下使用mapM_函数

3

我正在尝试将自相关的不同组件打印在不同的行上:

import Data.Vector as V
import Statistics.Autocorrelation
import Data.Typeable

sampleA = [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4]

main = do
    let res = autocorrelation $ V.fromList sampleA
    putStr "Type of result of autocorrelation test: "
    print $ typeOf res
    print res
    -- Prelude.mapM_ print res      -- not working; 

输出为:
Type of result of autocorrelation test: ((Vector Double),(Vector Double),(Vector Double))

([1.0,2.5e-2,-0.45,-0.325,0.5,0.125,-0.15],[1.0,-1.3255000000000001,-1.4039375473415425,-1.442999810318651,-1.5311377955236107,-1.5364636906417393,-1.544097864842309],[1.0,1.0755000000000001,1.1539375473415425,1.192999810318651,1.2811377955236107,1.2864636906417393,1.294097864842309])

然而,如果我取消最后一行的注释,就会出现错误:

No instance for (Foldable ((,,) (Vector Double) (Vector Double)))
    arising from a use ofPrelude.mapM_’
• In a stmt of a 'do' block: Prelude.mapM_ print res
  In the expression:
    do { let res = autocorrelation $ fromList sampleA;
         putStr "Type of result of autocorrelation test: ";
         print $ typeOf res;
         print res;
         .... }
  In an equation for ‘main’:
      main
        = do { let res = ...;
               putStr "Type of result of autocorrelation test: ";
               print $ typeOf res;
               .... }

如何将结果的所有部分打印在单独的行上?谢谢您的帮助。
3个回答

5
最简单的方法就是进行模式匹配。
main = do
    let (a,b,c) = autocorrelation $ V.fromList sampleA
    print a
    print b
    print c

1
我能以某种方式使用mapM或mapM_吗? - rnso
在这种情况下,是的,case autocorrelation (V.fromList sampleA) of (a,b,c) -> mapM_ print [a,b,c],因为a、b、c恰好是相同类型的Vector Double - Will Ness
谢谢。最好也把这个加入到你的回答中。 - rnso

4
如果您真的不想自己进行模式匹配,可以使用固定向量包来帮助您。请注意,它带有自己的mapM_,您必须使用它: the fixed-vector package
import Data.Vector as V
import qualified Data.Vector.Fixed as F
import Statistics.Autocorrelation
import Data.Typeable

sampleA = [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4]

main = do
    let res = autocorrelation $ V.fromList sampleA
    putStr "Type of result of autocorrelation test: "
    print $ typeOf res
    print res
    F.mapM_ print res

另一种方法是使用 newtype 并将元组放入其中:

{-# LANGUAGE DeriveFoldable #-}

import Data.Vector as V
import Statistics.Autocorrelation
import Data.Typeable

newtype Triple a = Triple (a, a, a) deriving(Foldable)

sampleA = [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4]

main = do
    let res = autocorrelation $ V.fromList sampleA
    putStr "Type of result of autocorrelation test: "
    print $ typeOf res
    print res
    Prelude.mapM_ print $ Triple res

2
我们可以使用 lens [Hackage] 包将元组转换为列表:
import Control.Lens(toListOf, each)
import qualified Data.Vector as V
import Statistics.Autocorrelation

sampleA = [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4]

main :: IO ()
main = mapM_ print (<b>toListOf each</b> (autocorrelation (V.fromList sampleA)))

但是最好像@DanielWagner所说的那样进行模式匹配,因为这样可以更明确地说明正在发生什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接