簡體   English   中英

申請真正適用於申請,而不是“結合”?

[英]How much is applicative really about applying, rather than “combining”?

對於不確定性傳播的Approximate類型 ,我想通過Monad獲得Functor實例。 然而,這不起作用,因為我需要在包含的類型上使用向量空間結構,因此它實際上必須是類的受限版本。 因為那些似乎仍然沒有標准庫(或者在那里?請指出我。有rmonad ,但它使用*而不是Constraint作為上下文類型,這似乎已經過時了),我寫了自己的暫時的版本

這一切對Functor都很容易

class CFunctor f where
  type CFunctorCtxt f a :: Constraint
  cfmap :: (CFunctorCtxt f a, CFunctorCtxt f b)  => (a -> b) -> f a -> f b

instance CFunctor Approximate where
  type CFunctorCtxt Approximate a = FScalarBasisSpace a
  f `cfmap` Approximate v us = Approximate v' us'
   where v' = f v
         us' = ...

但是直接翻譯Applicative ,就像

class CFunctor f => CApplicative' f where
  type CApplicative'Ctxt f a :: Constraint
  cpure' :: (CApplicative'Ctxt f a) => a -> f a
  (#<*>#) :: ( CApplicative'Ctxt f a
             , CApplicative'Ctxt f (a->b)
             , CApplicative'Ctxt f b)        => f(a->b) -> f a -> f b

是不可能的,因為函數a->b沒有必要的向量空間結構* FScalarBasisSpace

然而,有效的是改變受限制的應用類的定義:

class CFunctor f => CApplicative f where
  type CApplicativeCtxt f a :: Constraint
  cpure :: CAppFunctorCtxt f a  => a -> f a
  cliftA2 :: ( CAppFunctorCtxt f a
             , CAppFunctorCtxt f b
             , CAppFunctorCtxt f c )        => (a->b->c) -> f a -> f b -> f c

然后將<*>#而不是cliftA2定義為自由函數

(<*>#) = cliftA2 ($)

而不是方法。 如果沒有約束,那就完全等價了(事實上, 許多Applicative實例都是這樣的 ),但在這種情況下它實際上更好: (<*>#)仍然有a->b的約束, Approximate無法實現,但這並沒有傷害應用實例,我仍然可以做有用的東西,如

ghci> cliftA2 (\x y -> (x+y)/x^2) (3±0.2) (5±0.3)        :: Approximate Double 
0.8888888888888888 +/- 0.10301238090045711

我認為對於CApplicative許多其他用途,情況基本相同,例如已經在約束種類原始博客文章中給出的Set示例。

所以我的問題:

<*>比更基本liftA2

同樣,在無約束的情況下,無論如何它們都是等價的。 我實際上已經發現liftA2更容易理解,但在Haskell中,考慮傳遞“函數容器”而不是對象容器和一些“全局”操作來組合它們可能更自然。 <*>直接誘導所有liftAμμεℕ,不僅僅是liftA2 ; liftA2 那樣做只是不起作用

但是,這些受限制的類似乎為liftA2了一個重點。 特別地,它允許CApplicative所有實例CMonad S,時工作<*>#是基本方法。 而且我認為我們都同意Applicative應該總是比Monad更通用。

類別理論家對所有這些都說了什么? 有沒有辦法獲得一般liftAμ而不需要a->b需要滿足相關約束?


*該類型的線性函數實際上具有向量空間結構,但我絕對不能將自己局限於那些。

據我所知(作為非類別理論家),基本操作是zip :: fa -> fb -> f (a, b) (將一對有效計算映射到有效計算導致一對) 。

然后你可以定義

  • fx <*> fy = uncurry ($) <$> zip fx fy
  • liftA2 g fx fy = uncurry g <$> zip fx fy

請參閱Edward Yang發表的這篇文章 ,我通過Typeclassopedia找到了這篇文章

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM