簡體   English   中英

($)是(。),就像`fmap`是?

[英]($) is to (.) as `fmap` is to?

我有一個函數funcM :: a -> b -> c -> IO (x, y)

我想寫一個函數funcM_ :: a-> b-> c-> IO x所以:

funcM_ = fst `fmap` funcM -- error

我可以添加所有要點,但似乎應該可以用fmap替換fmap某些東西,以便上面的內容起作用。 有點像用(。)替換($)會使此工作在純上下文中進行。

我要尋找的功能是什么?

由於您要使用一個三參數函數( fmap )來構成一個單參數函數( funcM ),因此需要三個層次的合成:

funcM_ = ((fmap fst .) .) . funcM

通過簡單的擴展,它等同於指向版本:

funcM_ x = (fmap fst .) . funcM x
funcM_ x y = fmap fst . funcM x y
funcM_ x y z = fmap fst (funcM x y z)

這實際上來自fmap的類型:

fmap :: (Functor f) => (a -> b) -> f a -> f b

您只是將參數部分地應用於funcM以便獲得一個fa (在此為IO (x, y) ),將其賦予fmap fst以返回fbIO x )。

M_M_通常意味着返回m ()

請看以下答案: https ://stackoverflow.com/a/20279307/783743它說明了如何將代碼轉換為無點樣式。 讓我們從funcM_的非pointfree定義funcM_

funcM_ a b c = fmap fst (funcM a b c)

-- But `\x -> f (g x)` is `f . g`. Hence:

funcM_ a b = fmap fst . (funcM a b)

-- But `\x -> f (g x)` is `f . g`. Hence:

funcM_ a = (fmap fst .) . (funcM a)

-- But `\x -> f (g x)` is `f . g`. Hence:

funcM_ = ((fmap fst .) .) . funcM

做到這一點的另一種方法是使用uncurrycurry ,如下所示:

uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 f (a, b, c) = f a b c

curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d
curry3 f a b c = f (a, b, c)

(.::) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e
f .:: g = curry3 (f . (uncurry3 g))

現在,您可以編寫funcM_ ,如下所示:

funcM_ = fmap fst .:: funcM

您還可以按如下所示以無點樣式編寫.:: :::

(.::) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e
(.::) = (.) . (.) . (.)

希望能有所幫助。

funcM每個參數添加一個點

這些都是等效的:

((fmap fst . ) .) . funcM
((.)  . (.)  . (.))  (fmap fst) funcM
(fmap . fmap . fmap) (fmap fst) funcM

import Data.Functor.Syntax -- from 'functors' package
(.::) (fmap fst) funcM

注意,我所做的只是將隱式($)更改為(.) :-)

(.)Functor函數實例的fmap的實現:

instance Functor ((->) a) b where
  fmap f g = f . g

GHCi :t是您的朋友。

暫無
暫無

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

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