2012-07-08 20 views
9

Kaldırma ile örtme tanımlamak istiyorum. A => B fonksiyonuna sahip olduğumuzu varsayalım, belki de onu nasıl kaldıracağını tanımlamak istiyorum, belki [A] => Belki [B].Scala'da kaldırma işlevleri

Bu, yalnızca örtük dönüştürmelerle yapılabilir. Ancak, iki veya daha fazla parametreli fonksiyonlarla aynı şeyi yapmak istersem, bir sorunum var. Bildiğim tek çözüm, kodu çoğaltmak.

Herhangi bir çoğaltma yapılmadan herhangi bir sayıdaki parametrelerle keyfi işlevler için bu tür bir kaldırma uygulamak istiyorum. Scala'da bu mümkün mü? F kullanılabilen bir funktor örneği varsa

+2

Bakmaya değer olabilir: http://blog.tmorris.net/lifting/ –

+0

http://www.scala-lang.org/api/current/index.html#scala.Function2 adresine bakınız. , tupled fonksiyonu dikkat edin. Ayrıca http://www.scala-lang.org/api/current/index.html#scala.Function$ tupled ve untupled yöntemleri. – pedrofurla

cevap

18

, bu F[A] => F[B] herhangi fonksiyonunu A => B kaldırmak mümkündür.

F, kullanılabilir bir functor örneğine sahipse, A => B => C => .. => Z işlevini F[A] => F[B] => F[C] => .. => F[Z]'a kaldırmak mümkündür. Esasen, uygulama functor keyfi aritme için functor bir genelleme.

here ve here numaralı bisikletçiler ve uygulayıcı bisikletçiler hakkında bilgi edinebilirsiniz. Bu fikirleri kapsayan this mükemmel konuşma da var.

Scalaz kütüphanesi bu soyutlamaları (ve daha fazlasını!) Sağlar.

import scalaz._ 
import Scalaz._ 

scala> val foo: Int => String = _.toString 
foo: Int => String = <function1> 

scala> foo.lift[Option] 
res0: Option[Int] => Option[String] = <function1> 

scala> res0(Some(3)) 
res1: Option[String] = Some(3) 

scala> res0(None) 
res2: Option[String] = None 

scala> val add: (Int, Int) => Int = _ + _ 
add: (Int, Int) => Int = <function2> 

scala> add.lift[Option] 
res3: (Option[Int], Option[Int]) => Option[Int] = <function2> 

scala> res3(Some(2), Some(1)) 
res4: Option[Int] = Some(3) 

scala> res3(Some(2), None) 
res5: Option[Int] = None 

scala> res3(None, None) 
res6: Option[Int] = None 

Scalaz Function2 üzerinde lift yöntemi pezevenkler, Function3 vb syntactially ağır oldukları curried fonksiyonları daha az kullanılmaktadır, çünkü. Sahne arkasında, kaldırma işlemi Function1 s ile gerçekleşir (örn. Curried işlevleri).

Ayrıca Scalaz source code'a da bakmak isteyebilirsiniz.

+1

Garip bir şekilde 'foo.lift [Option] 'Scalaz 7 ile derlemiyor, ama' add.lift [Opsiyon] ' –

+1

@NikitaVolkov yapıyor, Sadece burada bir tahmin yaparak ... 1.' Functor [Opsiyon] .lift (foo) 've' Uygulacı [Seçenek] .lift2 (ekle) 'çalışabilir. Şu anda daha az "uzatma yöntemi" var. 2. Çoğu uzantı yöntemi hala bir scalaz.syntax paketinde mevcuttur. Aradığınız "asansör" orada uzanıyor olabilir. – missingfaktor

+0

, yukarıdaki kod Scalaz 7.1 ve Scala 2.11.5 üzerinde çalışacak mı? –