代码之家  ›  专栏  ›  技术社区  ›  Delfin

如何在Haskell中使用map打印列表?

  •  0
  • Delfin  · 技术社区  · 3 年前

    抱歉,如果我很傻,但是我是Haskell ans的初学者,我正在尝试用putStrLn打印列表,但我不确定如何解决下一个问题:

    我试着用Haskell的代码做一个基本的打印列表:

    import System.IO
    
    array = map show [1, 2, 3, 4]
    
    main :: IO ()
    main = do
      map putStrLn array
    

    但是编译器告诉我:

     8 main.hs:7:3: error:                                                                                                          
      7     • Couldn't match expected type ‘IO ()’ with actual type ‘[IO ()]’                                                            
      6     • In a stmt of a 'do' block: map putStrLn array                                                                              
      5       In the expression: do map putStrLn array                                                                                   
      4       In an equation for ‘main’: main = do map putStrLn array 
    

    1 回复  |  直到 3 年前
        1
  •  1
  •   Mark Saving    3 年前

    Haskell处理IO的方式与其他语言完全不同。

    在Java这样的语言中, System.Out.println(3) 是一个不计算为值的语句,因此您甚至不能编写 x = System.Out.println(3); .

    (print 3) 计算结果为3,在计算过程中,打印 3 . 所以说 (setq x (print 3)) x 还有印刷品

    在哈斯克尔, putStrLn "3" . 这样说 x = putStrLn "3" 去指挥部 输入“3” .

    让我们看看一些类型。我们有

    map :: (a -> b) -> [a] -> [b]
    putStrLn :: String -> IO ()
    

    因此,我们应该

    map putStrLn :: [String] -> [IO ()]
    map putStrLn array :: [IO ()]
    

    换句话说, map putStrLn array 是一个“IO操作”列表,其结果是类型为的值 () (基本上,这意味着执行操作不会产生额外的信息)。

    然而,为了写作

    main :: IO ()
    main = map putStrLn array
    

    那是什么

    main :: IO ()
    main = do map putStrLn array
    

    换言之,我们需要 map putStrLn 属于 IO () ,不是类型 [IO ()]

    如果希望对列表中的每个元素执行操作,可以使用 for_ 函数,它具有类型 for_ :: Applicative f => [a] -> (a -> f ()) -> f () IO Applicative ,尤其如此 for_ :: [String] -> (String -> IO ()) -> IO () 是一种 为了_ 我可以接受。代码看起来像

    import Data.Foldable (for_)
    
    array :: [String]
    array = map show [1, 2, 3, 4]
    
    main :: IO ()
    main = for_ array putStrLn
    

    这在命令式语言中相当于

    for each x in array do {
        putStrLn x;
    }