gpt4 book ai didi

haskell - Arrow 库中 `first` 的实现

转载 作者:行者123 更新时间:2023-12-01 23:36:29 27 4
gpt4 key购买 nike

我不明白 first 的实现在图书馆。
first似乎是用 *** 递归定义的——不知道递归什么时候结束!?

first :: a b c -> a (b,d) (c,d)
first = (*** id)


(***) :: a b c -> a b' c' -> a (b,b') (c,c')
f *** g = first f >>> arr swap >>> first g >>> arr swap
where swap ~(x,y) = (y,x)
first f(f *** id)这是 (first f >>> arr swap >>> first id...)和新 first将是另一个 (*** id)等等...

最佳答案

你是对的,如果你实现这样的箭头:

instance Arrow MyType where
arr f = ...

然后尝试使用 first(***) ,你会得到一个无限循环,因为实现之间没有效率地相互引用。但是,以这种方式定义默认方法允许您实例化 Arrow作为
instance Arrow MyType where
arr f = ...
first t = ...

或者
instance Arrow MyType where
arr f = ...
t *** t' = ...

哪个更方便/更有效(取决于您关心什么),并且缺少的方法将根据您指定的方法自动定义。

如果我们尝试实例化 Arrow没有给出 first 的实现或 (***) ,我们将收到以下警告:
warning: [-Wmissing-methods]
• No explicit implementation for
either ‘first’ or ‘***’
• In the instance declaration for ‘Arrow MyType’

这是因为 source自带 MINIMAL pragma :
{-# MINIMAL arr, (first | (***)) #-}

它告诉编译器,即使提供了默认值,除非指定 arr,否则实例是不完整的。和 first 之一或 (***) .所以需求被编码和检查。

至于你的评论:

Not necesseraly I can leave the default and then the recursion will take place by definition. specific implementation are not the question here...



你不能在没有实例的情况下使用类型类的方法。甚至很少尝试,因为方法的类型总是引用类型,例如
class Arrow k where
first :: k a b -> k (a,c) (b,c)
...

当您使用 first ,你必须有一个特定的 k记住以便使用结果,例如
print $ first (arr id) (1,2)                -- using it at k ~ (->)
print =<< runKleisli (first (arr id)) (1,2) -- using it at Kleisli IO

在某些时候,程序的类型约束将固定 k归结为具体的东西,这就是所使用的实例。没有实例就不能使用类。

(即使在事物以不确定特定实例的方式排列的情况下,经典示例是
show . read :: String -> String

编译器只会对你大喊大叫
• Ambiguous type variable ‘a0’ arising from a use of ‘read’
prevents the constraint ‘(Read a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.

如果程序不能编译,就没有无限递归!)

关于haskell - Arrow 库中 `first` 的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57744404/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com