loops - 修复与 ArrowLoop

标签 loops haskell arrows fixpoint-combinators

loop的描述来自 Control.Arrow :

The loop operator expresses computations in which an output value is fed back as input, although the computation occurs only once. It underlies the rec value recursion construct in arrow notation.



它的源代码,以及(->) 的实例化:
class Arrow a => ArrowLoop a where
    loop :: a (b,d) (c,d) -> a b c

instance ArrowLoop (->) where
    loop f b = let (c,d) = f (b,d) in c

这立刻让我想起了fix ,定点组合器:
fix :: (a -> a) -> a
fix f = let x = f x in x

所以我的问题是:
  • 是否有可能实现那个特定的 loop通过 fix ?
  • 它们的功能有何不同?
  • 最佳答案

  • 嗯,当然。每个递归定义都可以写成 fix :
    loop f b = let (c, d) = f (b, d) in c
    loop f b = fst $ let (c, d) = f (b, d) in (c, d)
    loop f b = fst $ let x = f (b, d) in x
    loop f b = fst $ let x = f' x in x
      where f' (_, d) = f (b, d)
    loop f b = fst $ fix $ f . (b,) . snd
    

    它反过来工作:
    fix f = loop (join (,) . f . snd) ()
    
  • 以上应该让你相信loopfix在谈论 (->) 时同样强大.那么,如果箭头用于泛化函数,为什么是 ArrowLoop不是这样定义的?
    class Arrow a => ArrowLoop a where
      fix :: a b b -> b
    

    箭头也概括了“过程”的概念:当 Arrow a , a b c是一种计算 c 的方法来自 b .如果 ArrowLoop被定义为直接概括 fix ,那么它就会严重瘫痪。 fix必须在没有任何上下文的情况下“执行”该过程并直接生成 b 类型的值,表示“进程”a b b不能,例如执行IO .或者,考虑箭头
    newtype LT i o = LT { runLT :: [i] -> [o] }
    

    如果 fix 你会喜欢它将产生 [b]来自 LT b b ,但事实并非如此。
    loop是绕过这些限制的一种方法。它将过程作为参数并产生过程作为结果。从某种意义上说,与第一个进程相关的所有上下文都可以在第二个进程中保留下来,如果 loop 是不可能的。更像 fix .

    请注意,我可以实现 fix 的模拟。对于 ArrowLoop年代:
    -- resulting process ignores its input
    fix' :: ArrowLoop a -- taking an impl of loop as argument
         => a b b -> a u b
    fix' f = loop ((id &&& id) . f . arr snd)
    -- take off the outer application to () (application means (->), after all)
    -- and arrowify: join (,) = id &&& id; snd = arr snd; (Prelude..) = (Control.Category..)
    -- but the RHSs are more general
    

    但我不相信
    loop' :: Arrow a => (forall x u. a x x -> a u x) -- taking an impl of fix' as argument
          -> a (b, d) (c, d) -> a b c
    

    是可实现的,所以我们不能基于 ArrowLoopfix'任何一个。
  • 关于loops - 修复与 ArrowLoop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51758376/

    相关文章:

    haskell - `\x -> ⊥ x` 是否等于(在 `seq` 之下)等于 `⊥` 、 `\x -> ⊥` 还是什么都没有?

    haskell - 没有 arr 的箭头

    死兔子的C++程序

    javascript - 在 Javascript 中,如何同时对两个 seqs 的元素执行一个函数?

    parsing - Haskell 的 Parsec <|> 运算符的问题

    haskell - 箭头是功能的真正概括吗?

    haskell - 关于箭头运算符的快速问题

    c - Openmp嵌套循环

    c - 如何在 C 中每行打印 10 个值,其中值按降序排列并且仅使用 while 循环和 if-else 语句?

    function - 将一个列表映射到另一个列表(在 Haskell 中,+抽象解决方案) - 'map reduce' ?