2011-11-19 14 views
7

bir Lambda fonksiyonunu ediyorum tekrar kullanımı bu kodu almak için:Ben sözde Haskell

f x y z = x^3 - g (x + g (y - g z) + g (z^2)) 
where g x = 2*x^2 + 10*x + 1 

nerede olmadan yeniden yazmak (veya izin).

Onlar Lambda fonksiyonu ile yazmaya demek (\ x -> ...) Ben Haskell bir Lambda fonksiyonunu yeniden çalışıyorum

. Herhangi bir fikir?

+6

'f = Flip ((1 +) p ((+). (2 *). (^ 2)) (10 *)). (çevir). ap ((.). (.). (.). (-). (^ 3)) (((ap id.).) Çevirme çevirin (flip id. (^ 2)). (liftM2 (liftM2 (+)).). (. ((ap id.). (. flip id). (.). (-))). (.). (.). (+)) ': f lambdabot tarafından anlamsız yapılan – fuz

cevap

12

, aşağıdaki şekilde bir lambda kullanarak özyinesiz let yazabilirsiniz:

let x = A in B  ==>  (\x -> B) A 
x bir değişkendir

ve A ve B ifadelerdir.

+5

Bu numara hakkında komik bulduğum şey, aslında Javascript'te standart bir uygulama olmasıdır. sadece işlevler orada bir kapsam bloğu oluşturabilir. – hugomg

+1

Yine de nasıl kullanabileceğimi anlayabildiğimden emin değilim – Asaf

+0

@Asaf: 'x''de B’ye birden çok kez bakabilirsiniz. Örneğin, '(\ x -> x + x) 3' seçeneğini kullanın. Bu, 3 + 3'e eşdeğerdir, sadece bir kere "3" yazmanız gerekmediği için. – hammar

8

Bir şeyi yeniden kullanmak için, bir şeye bir argüman yapabilirsiniz.

2

Bence bu amaç, bravit'in işaret ettiği şey.
smartypants takip-harfler-of-the-law geçici çözüm bir case ile g bağlayıcıdır;) de bravit ipuçları olarak

+2

Başka bir smartypants çözümü, en üst düzey bir işlev yapmaktır, çünkü bu, 'f' den hiçbir şeyi kapatmaz :) – hammar

2

Hammar'ın ve bravi'nin ipuçlarını genişletmek için, çözümünüz sadece bir lambda gerektirmeyecek, ancak ikisi - biri g gibi büyük bir şeye benzeyecek ve diğeri de ikincisi gibi büyük bir şeye benzeyecek lambda taşı g kullanma f

1

yarısı (\x -> 2*x^2 + 10*x + 1)

Yani f x y z = x^3 - g (x + g (y - g z) + g (z^2))

$> echo "f x y z = x^3 - g (x + g (y - g z) + g (z^2))" | sed -r -e 's/g/(\\x -> 2*x^2 + 10*x + 1)/g' 
f x y z = x^3 - (\x -> 2*x^2 + 10*x + 1) (x + (\x -> 2*x^2 + 10*x + 1) (y - (\x -> 2*x^2 + 10*x + 1) z) + (\x -> 2*x^2 + 10*x + 1) (z^2)) 

yılında bununla g yerine gerekecektir olduğunu ben Sadece şaka yapıyorum, üzgünüm.

+3

Eğitmenlerinin bu cevaptan daha az heyecan duyacağına eminim;) – Nate

+1

Bu tam olarak vereceğim cevaptır. Bildiğim kadarıyla, soru "burada, bu deyimsel kodu al ve daha kötüsünü yap, sadece X'i bildiğini kanıtlamak" anlamına gelir. Eğer öğretmen X'i tanımadığımı kontrol etmek istiyorsa, X'in gerçekten yararlı/gerekli olduğu bir soru ortaya koymalıdır. –

-1

Bu soru benim için ilginç ve ilginç görünüyor. Yani, ben lambda hesabı olduğunu, bir cevap bulmak ve OP (tüm ipuçları zaten, spoyler uyarısı gösterdi aslında gösterildi) göstermek istiyorum anlamaya çalışıyorum. fonksiyonu ve 3 rakamları elde cevap dönmek

λ> let f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2))) 
f :: 
    (Integer -> Integer) -> Integer -> Integer -> Integer -> Integer 

Yani, elimizdeki fonksiyonu,:

Öncelikle, f yeniden tanımlamak için deneyelim. Biz f_new = f g gibi burada g tanımını ekleyebilirsiniz ve tamamen kuruması kullanma: Bitirdik

λ> let f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2))) (\x -> 2*x^2 + 10*x + 1) 
f :: Integer -> Integer -> Integer -> Integer 

. Haydi kontrol edelim: Cevabınız evet.

UPD: bu örnekler let olarak

yorumlayıcı işlev bildirmek için bir yöntemdir, bu nedenle son cevap:.

f :: Num a => a -> a -> a -> a 
f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2))) (\x -> 2*x^2 + 10*x + 1)