Soru “<<” operatörü karada ne anlama geliyor?


Aşağıdaki koddan alınmıştır Elm Form Örneği, satır 122, ne yapar << operatör demek?

Field.field Field.defaultStyle (Signal.send updateChan << toUpdate) "" content

İçinde bulunamadı Elm sözdizimi referansı.

Bu, alanın değişmesi yerine, değiştiğinde anlamına geliyor mu? content için updateChangönder toUpdate için updateChan?


44
2017-12-12 10:29


Menşei


Haskell'den geliyorsanız: << analogu . Haskell'de - ZhekaKozlov


Cevaplar:


<< çekirdek kitaplığında tanımlanan bir işlev kompozisyon işleci Basics. Temel ilkelerden gelen tüm fonksiyonlar, niteliksiz Elm projelerine ithal edilir.

Elm'in tip sistemi

Elm tipi sistemin temellerini hatırlayalım.

Elm statik olarak yazılmıştır. Bu Elm'de her değişkenin veya fonksiyonun bir tipi olduğu ve bu türün hiçbir zaman değişmediği anlamına gelir. Elm'deki türlere örnekler:

  • Int
  • String
  • Maybe Bool
  • { name : String, age : Int }
  • Int -> Int
  • Int -> String -> Maybe Char.

Statik yazma, derleyicinin derleme sırasında tüm işlevlerin ve değişkenlerin türlerinin doğru olmasını sağladığından, çalışma zamanı türündeki hataların olmaması anlamına gelir. Diğer bir deyişle, asla bir tür işlevine sahip olmayacaksınız String -> String alma veya iade etme IntBuna izin veren kod bile derleme yapmaz.

Ayrıca, polimorfik fonksiyonlarınızı String veya Maybe Int gibi rasgele bir küçük harf olan bir tür değişkeni ile a. Birçok Elm çekirdek işlevi, örneğin polimorfik tiptir List.isEmpty türü var List a -> Bool. Bir alır List türden ve türden bir değer döndürür Bool.

Aynı tür değişkeni tekrar görüyorsanız, bu tür değişkenlerin örnekleri aynı türde olmalıdır. Örneğin List.reverse türü var List a -> List a. Eğer başvurursan List.reverse tamsayıların listesine (yani, bir şeye sahip olan bir şeye List Int), o irade tam sayıların bir listesini döndür. Böylesi bir işlev tamsayıların listesini almaz, ancak dizelerin bir listesini döndürür. Bu derleyici tarafından garanti edilir.

Elm'deki tüm fonksiyonlar curried varsayılan olarak. Bu, 2 argümandan oluşan bir fonksiyona sahipseniz, 1 argüman fonksiyonunu döndüren 1 argüman fonksiyonuna dönüştürülür. Bu nedenle, Elm'in uygulama sözdizimini, Java, C ++, C #, Python, vb. Diğer dillerde fonksiyon uygulamasından çok farklı bir şekilde çalıştırırsınız. Yazmak için bir neden yoktur. someFunction(arg1, arg2)yazabilirsin someFunction arg1 arg2. Niye ya? Çünkü gerçekte someFunction arg1 arg2 aslında ((someFunction arg1) arg2).

Currying yapar kısmi uygulama mümkün. Kısmen uygulamak istediğinizi varsayalım List.member. List.member bir türü var a -> List a -> Bool. Yazıyı “okuyabiliriz”List.member türden 2 argüman alır a ve yazın List a”. Ama biz de türünü “okuyabiliriz”List.member 1 argüman alır a. Bir tür işlevi döndürür List a -> Bool”. Bu nedenle bir işlev oluşturabiliriz isOneMemberOf = List.member 1türüne sahip olacak List Int -> Bool.

Bu şu demek -> İşlevlerin tip açıklamalarında doğru ilişkilendirilebilir. Diğer bir deyişle, a -> List a -> Bool aynıdır a -> (List a -> Bool).

Infix ve ön ek gösterimi

herhangi infix operatörü aslında perde arkasında sıradan bir işlevdir. Sadece bir fonksiyon ismi sadece alfanümerik olmayan sembollerden oluştuğunda ($, <|, <<, vb.), Önlerinde değil (sıradan fonksiyonlar gibi) 2 argüman arasında yer alır.

Ama yine de ikili bir operatör gibi + 2 argümanın önünde, parantez içine alınarak, aşağıdaki 2 fonksiyon uygulaması eşdeğerdir:

2 + 3 -- returns 5
(+) 2 3 -- returns 5, just like the previous one

Infix operatörleri sadece sıradan işlevlerdir. Onlar hakkında özel bir şey yok. Bunları başka bir işlev gibi kısmen uygulayabilirsiniz:

addTwo : Int -> Int
addTwo = (+) 2

addTwo 3 -- returns 5

İşlev bileşimi

(<<) çekirdek kitaplığında tanımlanan bir işlev kompozisyon işleci Basics. Temel özelliklerden gelen tüm fonksiyonlar Elm projelerine niteliksiz olarak aktarılır, yani yazmak zorunda değilsiniz import Basics exposing (..), zaten varsayılan olarak yapılır.

Yani diğer herhangi bir operatör gibi (<<) Diğerleri gibi sadece bir işlevdir. Türü nedir?

(<<) : (b -> c) -> (a -> b) -> a -> c

Çünkü -> doğru-birleştirici, bu eşdeğerdir:

(<<) : (b -> c) -> (a -> b) -> (a -> c)

Diğer bir deyişle, (<<) 2 çeşit fonksiyon alır b -> c ve a -> b sırasıyla ve bir işlev döndürür a -> c. Biri içine 2 fonksiyonu oluşturur. Bu nasıl çalışıyor? Sadelik için uğruna bir örnek bakalım. 2 basit fonksiyonumuz olduğunu varsayalım:

addOne = (+) 1
multTwo = (*) 2

Varsayalım (+), bir tek addOne, 3'ü değil, 1'i ekleyen bir işlevi nasıl oluşturabiliriz? Çok basit, biz oluştururuz addOne 3 kez birlikte:

addThree : Int -> Int
addThree = addOne << addOne << addOne

Ya 2, sonra katları 4 ekleyen bir işlev oluşturmak istiyorsak?

ourFunction : Int -> Int
ourFunction = multTwo << multTwo << addOne << addOne

(<<) Sağdan sola doğru fonksiyonlar oluşturur. Ancak yukarıdaki örnek basittir, çünkü tüm türler aynıdır. Listenin bütün küplerinin bir miktarını nasıl bulabiliriz?

isEven : Int -> Bool
isEven n = n % 2 == 0

cube : Int -> Int
cube n = n * n * n

ourFunction2 : List Int -> Int
ourFunction2 = List.sum << filter isEven << map cube

(>>) aynı işlevdir, ancak argümanlar çevrilirken, aynı bileşimi soldan sağa yazabiliriz:

ourFunction2 = map cube >> filter isEven >> List.sum

tekrarlamak

Gibi bir şey gördüğünde h << g << fo zaman biliyorsun f, g, h işlevler. Bu yapı ne zaman h << g << f bir değere uygulanır xsonra bilirsin:

  • Elm önce geçerlidir f için x
  • o zaman uygular g önceki adımın sonucuna
  • o zaman uygular h önceki adımın sonucuna

bu nedenle (negate << (*) 10 << sqrt) 25 eşittir -50.0çünkü ilk önce 25'in karekökünü alıp 5 tane al, sonra 5 ile 10'u çarp ve 50 tane al, sonra 50'yi reddet ve -50'yi al.

Neden << ve değil.

Elm 0.13'ten önce (bkz. duyuru) işlev bileşimi operatörü (.)ve davranışı şu ankiyle aynıydı (<<). (<<) F # dilinden Elm 0.13'te kabul edildi Github sorunu). Elm 0.13 de eklendi (>>) eşdeğer olarak flip (<<), ve (<|) Fonksiyon uygulama operatörü yerine ($), ve (|>) eşdeğer olarak flip (<|).

İnfix işlev çağrısı

Olağan bir alfasayısal işlev adını infix ikili operatörüne dönüştürebileceğinizi merak ediyor olabilirsiniz. Elm 0.18'den önce, bir fonksiyon infix'i yapmak için backticks kullanacaksınız, bu yüzden 2'nin altında eşdeğer olacaktır:

max 1 2 -- returns 2
1 `max` 2 -- returns 2

Elm 0.18 bu özelliği kaldırdı. Artık Elm'de yapamazsın, ama dil gibi Haskell ve PureScript hala sahip.


96
2017-08-18 16:50



Keşke bu adam benim hocam olsaydı. Bu, işlevsel ML temelli dillerdeki yeni başlayanlar için bazı kritik bilgileri içermemem gereken resmi belgelerde olmalıdır. - frostymarvelous


<< bir fonksiyon bileşimidir - işlevi döndürür.

Kompozisyon, bir hesaplama borusu, fonksiyon zinciri oluşturur. Bu boru girişi bekler ve sağlandığında, ilk işlev hesaplamayı başlatır, çıktıyı bir sonraki sayfaya gönderir.

import Html

add x y =
    Debug.log "x" x + Debug.log "y" y

add9 =
    add 4 << add 5

main =
    Html.text <| toString <| add9 2

Not: Yukarıdaki örnekte kullanıyorum kısmi uygulama. Bu, tüm parametrelerin işlevini yerine getirmemesi ve sonuç olarak işlev almam anlamına gelir.

Örnegin web tarayicida calisir ve konsol çıktısına bakarsan göreceksiniz:

x: 5
y: 2
x: 4
y: 7

Eğer matematik işlemleri olarak yazarsak, şöyle görünecektir:

4 + (5 + 2)
4 + 7

Not: İleri sürümü de kullanabiliriz >>.

İmza okuma

Bu operatörün imzasına bakarak:

(<<) : (b -> c) -> (a -> b) -> a -> c

İçin << operatör, bir fonksiyon var b -> c ilk parametre ve bir işlev olarak a -> b ikinci olarak:

(b -> c) << (a -> b)

Ama üçüncü bir parametre de var a. Çünkü -> doğru-ilişkisel, o zaman

(<<) : (b -> c) -> (a -> b) -> a -> c

eşdeğerdir:

(<<) : (b -> c) -> (a -> b) -> (a -> c).

Böylece << işlev döndürür a -> c.

Birleşim

Programlama dillerinde, bir operatörün ilişkilendirilmesi (veya sabitliği), parantezin yokluğunda aynı öncelikli operatörlerin nasıl gruplandığını belirleyen bir özelliktir; yani her operatörün hangi sırayla değerlendirildiği:

a = b = c olarak ayrıştırıldı a = (b = c)

İnfix operatörü

İşte kullanıyorum << gibi infix operatörüAncak bunu parantez içine alan bir önek operatörü olarak da kullanabiliriz: (<<) (b -> c) (a -> b) veya (<|) (add 4) (add 5).

elm <0,18 alışığım normal işlevleri alıp infix operatörleri olarak kullanmanıza izin verin.

Hakkında bir kelime <| Şebeke

<| bir fonksiyon uygulaması - değer döndürür

Temel olarak onu parantez yerine kullanıyoruz.

text (something ++ something)

olarak yazılabilir

text <| something ++ something

Yani bakmak imza bu operatörün

(<|) : (a -> b) -> a -> b

bunu görebiliriz <| operatör, bir fonksiyon var a -> b  ilk parametre ve değer olarak a ikinci olarak:

(a -> b) <| a

ve döner b.

Fonksiyon değeri ile aynı değeri alabiliriz <|:

v1 = add 4 <| add 5 <| 4
v2 = (add 4 << add 5) 4

19
2018-05-29 12:41



Nitpick için özür dilerim, ancak bu bağlamda "tembel fonksiyon zinciri" midir? Elm kesinlikle değerlendirilmedi mi? groups.google.com/forum/#!topic/elm-discuss/9XxV9L0zoA0 - pdoherty926


Bu fonksiyon bileşimi. Somut örneğiniz için

\x -> (Signal.send updateChan (toUpdate x))

Karaağaç'da, sözdiziminin bir parçası değil, standart kitaplığın bir parçası: Temelleri. <<


11
2017-12-12 10:46



Fakat << iki işlevi alırsa f ve g ikisi de fonksiyonlar, bunu görebiliyorum f << g anlamına geliyor \x -> f (g x). Benim örneğimde kiminle toUpdate kompozit, bazı gizli kimlik fonksiyonu? Dan beri updateChan yazıyorsan, bir işlev değil updateChan << toUpdateBu hata neden olmaz mıydı? - Not an ID
Bu snippet'i sağladığınız kaynakları bulamadım. itibaren send ve Saha imzaları Bazı Veri tiplerinin orada kullanıldığını varsaydım. updateChan bir Channel Data ve toUpdate formun bir işlevidir String -> Data. Bu verir (Signal.send updateChan) türü var Data -> Message ve (Signal.send updateChan) << toUpdate türü var String -> Message. - CheatEx


İkinci denemem: D

<< vs <|

Arasındaki fark << ve <| bu mu << fonksiyonları oluşturmak için kullanılır ve <| parantezleri çıkarmak için kullanılır.

Neden böyle çalışıyor?

Tür açıklamalarına bakalım İşte:

<< : (b -> c) -> (a -> b) -> a -> c

Bu tanım bize, işlevlerini yerine getirmek için iki işlevi geçtiğini söyler. <<, fonksiyon alacaksın a -> c.

İle örnek gösteri

hi a =
    a + 2
hello a =
    a * 2
bye =
    hello << hi
c =
    bye 3

c değer döndürür 10.

Hakkında daha fazla bilgi edinin:

  • infix operatörleri - işlevin solundaki ilk argüman,
  • kısmi uygulama - Bir argümanı iki argüman bekleyerek fonksiyona aktardığınızda, bir argüman bekletme fonksiyonuna sahip olursunuz.

0
2017-07-29 21:05