2011-07-14 20 views
8

i Haskell acemi değilim ve ben sorum var: yazıyorum kod:haskell ve dize uzunluğu

word_list = ["list", "lol", "wordword"] 
check str = if head str == 'l' then tail str else str 
average wl = (length $ concat $ map check wl) `div` length wl 

kelime listesindeki her kelimenin ilk "l" sembolü silmelisiniz bu kod, concat alınan kelimeler , kelime sayısı üzerinde sonuç dizesi ve div uzunluğunu alın. (= 13 "istolwordword", "listlolwordword" = 15) 13/3 = 4.333 ... ama ben sadece 4.

average :: [[Char]] -> Float çalışmaz alma:

nedenle bu kodda ı alma zorundadır hata alıyorum. benim hatam nerede? ps. Özür ingilizcem, lütfen

cevap

12

length işlev Int döndürür ve div fonksiyon başka bir deyişle, bu kesirli kısmını düşer tamsayı bölme yapar. Bunda olduğum sürece

word_list = ["list", "lol", "wordword"] 
check str = if head str == 'l' then tail str else str 
average wl = fromIntegral (length $ concat $ map check wl)/fromIntegral (length wl) 

, bunun yerine check eşleşen desen kullanmayı düşünmelisiniz: Bir Float sonuç istiyorsanız, önce, sonra bir Float için length sonucunu dönüştürmek yerine bölünmesi için (/) kullanmak gerekir Örneğin:

check ('l':str) = str 
check str = str 

Bu stil hem daha okunaklı ve yanlışlıkları olması olasılığı daha düşüktür - boş bir dize verilirse örneğin, sürüm başarısız olur.

+0

vay. Size çok teşekkür ederim! Desen eşleştirme hakkında : şaşırtıcı! Her gün hasskel'i daha çok seviyorum :) –

+1

@user: Ayrıca concatMap olduğunu unutmayın, böylece "concat $ map" yapmak zorunda değilsiniz. –

+1

ve ben daha açık bir yaklaşım muhtemelen 'toplam $ harita (uzunluk. Kontrol edin) wl' olduğunu (fusion muhtemelen bu önemsiz hale getirir) – alternative