Wpis z mikrobloga

#programowaniefunkcyjne #haskell #programowanie

Mam takie zadanko:

Niech będzie dany następujący typ drzew:

data Tree a b = Leaf a | Node a b (Tree a b) (Tree a b)
Proszę zdefniować funkcję map' b f t, która zastosuje funkcję f do wszystkich elementów typu b.


Nie do końca wiem jak się za to zabrać - z tego co zdążyłem na stacku wyczytać w Haskellu nie ma możliwości w "runtime'ie" sprawdzić typ podstawionego argumentu, jak mam zatem sprawdzać, czy dany element drzewa faktycznie jest np. Node'm/Leaf'em? Mam napisać kilka deklaracji tej samej funkcji z określeniem przyjmowanego typu i typu który jest obecnie "brany pod uwagę" dla wszystkich możliwości?
  • 9
@xwlk: Generalnie chyba muszę sobie jakoś uprościć ten typ Tree, bo się gubię już w tych wszystkich literkach :D No i ogarnąć Pattern Matching, bo faktycznie wygląda, że jest to odpowiedź na moje pytanie - w prostych przykładach sobie radzę, ale tutaj wymiękłem.

Edit: Zapomniałem podziękować - dzięki za wskazówki :)
@xwlk: Czyli w moim przypadku lewa strona definicji powinna wyglądać w ten sposób? (zmieniłem nazwę funkcji dla czytelności, nie podoba mi się ten apostrof ;/)

mapTree (Node a b c d) f (Leaf e) =
mapTree (Node a b c d) f (Node a b c d) =
mapTree (Leaf a) f (Leaf a) =
mapTree (Leaf e) f (Node a b c d) =

Rozumiem to tak - jeżeli oczekiwany
@asunez: Generalnie zacznij od zdefiniowania typow jakie funkcja bedzie przyjmowala i jakie zwracała.
Potem właśnie musisz w obsluzyc wszystkie przypadki odpowiednimi wzorcami i zaleznie od tego co zostało zmatchowane odpowiednio zareagować.

Nie do końca widzę to co napisaleś, z grubsza bedzie to cos takiego:

mapTree :: (Tree a b) -> .......
mapTree Leaf(a) = Leaf(f(a))
mapTree Node(....) => costam innego
@xwlk: dobra, spróbuję się odbić jakoś od Twojego rozwiązania, może wtedy dobrze to zrozumiem. Nie zawracam już głowy, dzięki raz jeszcze ( ͡° ͜ʖ ͡°)
Nie moge edytowac, tutaj masz pelniejszy kod, ale musisz rozpracowac reszte:

mapTree :: ... -> (Tree a b) -> ....... -> (Tree x b)
mapTree Leaf(a) = Leaf(f(a))
mapTree Node(....) => costam innego

zauwaz ze po drodze moze zmienic sie typ z a na x bo funkcja f moze zwracac inny typ niz a. Moglem gdzies zrobic blad po drodze ale ogolnie taka jest idea
@xwlk: Właśnie z tymi zmianami typu mam chyba największy problem, bo dopasowania wcześniej już robiłem, ale nie na tyle argumentów i po prostu się gubię w tym ;P
@asunez: No można się w tym zgubić :) Generalnie dla mnie najłatwiej zawsze najpierw napisać deklarację funkcji i typów, potem wypełnic implementację