2017-03-05 17 views
1

enter image description here在書中編寫函數`selfApp` *類型和編程語言*在scala中

可以寫這個函數是Scala嗎?或者其他語言?

+0

對於我們這些沒有Lambda微積分背景的人,請翻譯一下符號。 – davidrpugh

+0

@davidrpugh像'selfApp(f:[X] X => X):[X] X => X = f(f)'(這實際上不是合法的語法)。 – sepp2k

+0

「可以寫這個函數是Scala還是其他語言?」 - 是的。事實上,你已經在你的問題中以「任何其他語言」發佈了一個實現。 –

回答

2

我不認爲這是可能的在Scala沒有包裝在一個額外的對象的功能。這樣做的一個方法是:

type XtoX = {def apply[X](x: X): X } 
def selfApp(f: XtoX): XtoX = f(f) 

現在,您可以定義一個對象具有適當類型的應用方法是這樣的:

object ID { def apply[X](x: X): X = x } 

並調用selfAppselfApp(ID),這將直接返回它給出的對象。然而,這不起作用:

def id[X](x: X): X = x 

selfApp(id) 

你也不能使用匿名函數x => x。這是因爲當傳遞方法或匿名函數時,表示爲FunctionN對象,並且FunctionN特徵具有單態(即非泛型)功能。所以你需要自己使用一個通用的apply方法明確地創建一個對象。


在Haskell中,你可以通過使用RankNTypes擴展這樣做沒有任何包裝:

{-# LANGUAGE RankNTypes #-} 
selfApp :: (forall x. x -> x) -> (forall x. x -> x) 
selfApp f = f f 

,當然還有在動態類型語言,你可以只寫功能,無需擔心類型。例如在Python中:

def id(x): return x 
def selfApp(f): return f(f) 
print(selfApp(id)(42)) # Just works - no extensions, no wrapping, no nothing 
+0

http://scalaz.github.io/scalaz/scalaz-2.9.0-1-6.0.1/doc.sxr/scalaz/Forall.scala.html#13208所以RankNTypes被實現爲scala/java中的對象吧? – molikto

+0

@molikto是的,或者更確切地說:所有函數都是以Scala中的對象的形式實現的,但是更高級的函數需要表示爲實現自定義特徵的對象(與'scala.Function1'相反)。 – sepp2k