SORU
21 Mart 2010, Pazar


Neden Haskell yan etkileri monadlar olarak modellenmiş?

Herkes Haskell içinde unpure hesaplamaları monadlar olarak modellenmiş neden bazı işaretçiler verebilir misiniz?

Ben monad 4 işlemleri ile sadece bir arayüz demek, modelleme için akıl yan etkileri ne oldu?

CEVAP
21 Mart 2010, Pazar


Bir işlev yan etkisi yoktur sanırım. Eğer giriş ve çıkış parametreleri olarak üretmek tüm etkileri ele alırsak işlevi dış dünyaya saf.

Saf olmayan bir fonksiyon için

f' :: Int -> Int

göz için Gerçek dünya ekliyoruz

f :: Int -> RealWorld -> (Int, RealWorld)
-- input some states of the whole world,
-- modify the whole world because of the a side effects,
-- then return the new world.

sonra f saf yine. Biz Gerçek dünya o kadar çok türü gerek yok yani parametrize veri türü IO a = RealWorld -> (a, RealWorld) tanımlayın

f :: Int -> IO Int

Programcı, doğrudan Gerçek dünya kullanım çok tehlikeli -; eğer bir programcı türü Gerçek değeri ele geçirirse özellikle, alabilirkopyalaesasen imkansız olduğu gibi. (Tüm dosya sistemi taklit etmeye çalışan düşünün, örneğin. Nereye koyardın?) Bu nedenle, IO'NUN bizim tanım olarak bütün dünya devletleri saklar.

Bu saf olmayan işlevleri eğer onları bir araya zincir miyiz diye mi işe yaramaz. Düşünün

getLine :: IO String               = RealWorld -> (String, RealWorld)
getContents :: String -> IO String = String -> RealWorld -> (String, RealWorld)
putStrLn :: String -> IO ()        = String -> RealWorld -> ((), RealWorld)

Bir dosya adı konsolu almak istiyoruz, bu dosya okumak, içeriği yazdırın. Nasıl gerçek dünya devletleri ulaşabilirsek yapardık?

printFile :: RealWorld -> ((), RealWorld)
printFile world0 = let (filename, world1) = getLine world0
                       (contents, world2) = (getContents filename) world1 
                   in  (putStrLn contents) world2 -- results in ((), world3)

Burada bir örüntü görüyoruz: işlevleri şöyle: denir

...
(<result-of-f>, worldY) = f worldX
(<result-of-g>, worldZ) = g <result-of-f> worldY
...

Operatör ~~~ bağlamak için onları tanımlayabiliriz:

(~~~) :: (IO b) -> (b -> IO c) -> IO c

(~~~) ::      (RealWorld -> (b, RealWorld))
      -> (b -> RealWorld -> (c, RealWorld))
      ->       RealWorld -> (c, RealWorld)
(f ~~~ g) worldX = let (resF, worldY) = f worldX in
                        g resF worldY

o zaman sadece yazabiliriz

printFile = getLine ~~~ getContents ~~~ putStrLn

gerçek dünyaya dokunmadan.


Şimdi dosyayı büyük da içerik yapmak istiyorum varsayalım. Uppercasing saf bir fonksiyonudur

upperCase :: String -> String

Ama gerçek dünyaya yapmak, IO String bir dönüş var. Kolay böyle bir işlevi kaldırmak için:

impureUpperCase :: String -> RealWorld -> (String, RealWorld)
impureUpperCase str world = (upperCase str, world)

bu genelleştirilmiş:

impurify :: a -> IO a

impurify :: a -> RealWorld -> (a, RealWorld)
impurify a world = (a, world)

impureUpperCase = impurify . upperCase ve yazmak

printUpperCaseFile = 
    getLine ~~~ getContents ~~~ (impurify . upperCase) ~~~ putStrLn

(Not: Normalde ** 31) yazıyoruz


Şimdi gelelim ne yaptığımıza bakın:

  1. İki saf olmayan işlevleri birlikte zincirleri 32* *bir operatör tanımladık
  2. Saf saf bir değeri dönüştüren bir fonksiyon impurify :: a -> IO a tanımladık.

Şimdi kimliği (>>=) = (~~~) ** 35, ve biz yapmak? Bir monad var.


(Gerçekten birkaç aksiyom var bir monad olup olmadığını kontrol etmek için tatmin edici olmalıdır:

(1) return a >>= f = f a

  impurify a               = (\world -> (a, world))
 (impurify a ~~~ f) worldX = let (resF, worldY) = (\world -> (a, world)) worldX 
                             in f resF worldY
                           = let (resF, worldY) =            (a, worldX))       
                             in f resF worldY
                           = f a worldX

(2) f >>= return = f

  (f ~~~ impurify) a worldX = let (resF, worldY) = impuify a worldX 
                              in f resF worldY
                            = let (resF, worldY) = (a, worldX)     
                              in f resF worldY
                            = f a worldX

(3) f >>= (\x -> g x >>= h) = (f >>= g) >>= h

Egzersiz.)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Lupe Fiasco

    Lupe Fiasco

    23 ŞUBAT 2006
  • theatre2film

    theatre2film

    12 NİSAN 2006
  • WestsideMrArO

    WestsideMrAr

    6 EKİM 2010