【问题标题】:2 similar Haskell functions using do notation return same result but one is called many more times2 个使用 do 表示法的类似 Haskell 函数返回相同的结果,但其中一个被调用多次
【发布时间】:2021-07-14 19:35:07
【问题描述】:
nextState :: IO Int -> IO Int -- 0 1 0 2 0 1 0
nextState stateIO = do
  value <- stateIO
  putStrLn $ "Current state: " ++ show value
  fmap (+1) stateIO

nextState' :: IO Int -> IO Int -- 0 1 2
nextState' stateIO = do
  value <- stateIO
  putStrLn $ "Current state: " ++ show value
  return $ value + 1

main :: IO ()
main = do
  let startStateIO = return 0 :: IO Int
  let states = iterate nextState' startStateIO -- Use nextState or nextState'
  stateInt <- states !! 3
  print stateInt -- 3 in both cases

这个 Haskell 代码有 2 个函数,它们看起来都具有相同的行为。但是,打印调用显示nextState 被调用的次数比nextState' 多得多。 我有一个更大的项目,这是一个问题,我不知道如何转换该函数,以便它被调用的最少次数,所以我无法修复它。

为什么会发生这种情况,在一个不太简单的例子中如何防止它发生?

请注意,我的实际项目中的fmap (+1) 只是IO a -&gt; IO a 的一个函数,而不是fmap (a -&gt; a) - 整个事情都在IO 方面起作用,而不是使用(a-&gt;a) 修改里面的值

【问题讨论】:

    标签: haskell recursion optimization


    【解决方案1】:

    这个例子应该比较容易理解,类比:

    twice :: IO () -> IO ()
    twice act = do
       () <- act
       fmap id act -- like what you did in `nextState`
    
    once :: IO () -> IO ()
    once act = do
       () <- act
       return $ id ()  -- like what you did in `nextState'`
    

    ...或更短

    twice :: IO () -> IO ()
    twice act = act >> act
    
    once :: IO () -> IO ()
    once act = act
    

    例如,

    > twice (putStrLn "hello")
    hello
    hello
    > once (putStrLn "hello")
    hello
    

    迭代once 没有任何作用,因为它只是身份。

    > iterate once (putStrLn "hello") !! 4
    hello
    

    但是迭代两次...

    Prelude> iterate twice (putStrLn "hello") !! 4
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-27
      • 1970-01-01
      • 1970-01-01
      • 2019-12-19
      • 1970-01-01
      • 2019-05-22
      • 1970-01-01
      相关资源
      最近更新 更多