2017-04-11 16 views
1

如果我有一個功能(例如類型a -> b的)包裹在一個Applicative和可施加到其上的值(即在上述示例中a類型的值),I可以如下應用它:預定義的Haskell運算符用於在Applicative中應用純數值?

doSomething :: Applicative f => f (a -> b) -> a -> f b 
doSomething wrappedFn arg = wrappedFn <*> (pure arg) 

我發現自己做了很多。是否有標準的預定義運算符可以使代碼更加簡潔,還是我需要自己定義一個?如果是後者,是否有傳統的名稱?

+1

[本?](http://hayoo.fh-wedel.de/?查詢=應用程序+ f +%3D%3E + f +%28a + - %3E + b%29 + - %3E + a + - %3E + f + b) – Alec

+2

請注意,'doSomething'不能節省您輸入的時間。它只是通過調用'doSomething'來代替'<*>'和'pure'的調用。重要的是,它不會擴展到2+參數函數,特別是如果你想允許一些參數是純的而且有些被包裝的話。我認爲僅僅編寫'純x'和'f <*> x <*>純y''可讀性更好。 – amalloy

+0

@Alec - 是的,這似乎是我正在尋找的。想知道爲什麼hoogle沒有找到它...... – Jules

回答

6

有一個標準的,預定義的操作符,可以使代碼更加簡潔......?

...還是我需要定義一個自己?

是的(除非你想導入外部軟件包)。

如果是後者,是否有一個傳統的名字呢?

鏡頭中叫做(??),有的有other names。根據鏡頭,它是flip廣義變型,這是有道理的:

flip ::    (a -> b -> c) -> b -> a -> c 
(??) :: Functor f => f (b -> c) -> b -> f c 

替代f((->) a,你會得到從(??)flip。因此,您可以將其稱爲廣義翻轉

順便說一句,你不需要ApplicativeFunctor足夠:

gFlip :: Functor f => f (a -> b) -> a -> f b 
gFlip f x = fmap ($x) f 

一些例子:

ghci> gFlip [(+ 1),(* 2)] 2 
[3, 4] 
ghci> gFlip (++) "world" "hello" 
"helloworld" 
3

有實際上是該運營商的中等知名的版本,即(??) from lens

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

注意Functor約束。事實證明Applicative沒有必要,因爲它可以定義爲\f x -> ($ x) <$> f

的規範使用情況(??)與功能的仿函數,作爲綴flip

GHCi> execState ?? [] $ modify (1:) 
[1] 

在一般情況下,這不正是你想要什麼:

GHCi> [negate] ?? 3 
[-3] 

(就個人而言,我仍然覺得[negate] <*> pure 3更具可讀性,但情況因人而異。)

+2

就我個人而言,我發現'[negate 3]'或'[-3]'更具可讀性:D。 – Zeta

+1

@澤塔我可能應該更新我的微不足道的例子:D – duplode