2013-06-28 1 views
5

Я все еще очень стараюсь попасть в хакелл, но я заметил кое-что, что меня очень раздражало.Почему не шоу рассматривается как конверсия в haskell?

В этой книге "Learn You a Haskell for Great Good!" есть эта часть, которая показывает использование охранников в соответствии с шаблоном, в случае книги это была небольшая функция, которая вычисляет bmi человека, это немного изменилось (части изменены немного не нарушать авторские права или любой другой):

bmiCalc :: (RealFloat a) => a -> a -> String 
bmiCalc weight height 
    | bmi <= 18.5 = "skinny" 
    | bmi <= 25.0 = "normal" 
    | bmi <= 30.0 = "fat" 
    | otherwise = "obese" 
    where bmi = weight/height^2 

это все хорошо и денди код работает как рекламируется, но я подумал, что, если он также показал, что BMI она рассчитана была вместе с текстом?

Так что я переписал код для этого:

bmiCalc :: (RealFloat a) => a -> a -> String 
bmiCalc weight height 
    | bmi <= 18.5 = "skinny, " ++ show bmi 
    | bmi <= 25.0 = "normal, " ++ show bmi 
    | bmi <= 30.0 = "fat, " ++ show bmi 
    | otherwise = "obese, " ++ show bmi 
    where bmi = weight/height^2 

Ожидая «шоу», чтобы работать, как .ToString делает в Java и C#
Мальчик я был неправ.

GHCi дал мне это большое противное сообщение об ошибке:

Could not deduce (Show a) arising from a use of `show' 
from the context (RealFloat a) 
    bound by the type signature for 
      bmiCalc :: RealFloat a => a -> a -> String 
    at file.hs:1:16-48 
Possible fix: 
    add (Show a) to the context of 
    the type signature for bmiCalc :: RealFloat a => a -> a -> String 
In the second argument of `(++)', namely `show bmi' 
In the expression: "skinny, " ++ show bmi 
In an equation for `bmiCalc': 
    bmiCalc weight height 
     | bmi <= 18.5 = "skinny, " ++ show bmi 
     | bmi <= 25.0 = "normal, " ++ show bmi 
     | bmi <= 30.0 = "fat, " ++ show bmi 
     | otherwise = "obese, " ++ show bmi 
     where 
      bmi = weight/height^2 
Failed, modules loaded: none. 

почему? почему он не позволяет мне добавить то, что, кажется, возвращает строку, в строку? Я имею в виду, насколько я понял, "skinny, " ++ show bmi - это строка ... это именно то, что говорит подпись типа, я должен вернуть

, так что я сделал здесь неправильно?

+1

Вы пробовали предложение из сообщения об ошибке (сразу после «Возможное исправление»)? – Yuras

+2

Сопоставимый эквивалент Java будет заключаться в том, что 'show' - это метод интерфейса' Show', и для этого интерфейса не требуется значение 'a', поэтому существует ошибка проверки типа компиляции - то же самое, что было бы на Java. –

+0

Раньше было, что typeclass 'RealFloat' имел' Show' в качестве одного из своих предварительных условий (через 'Num'), но это изменилось не так давно. LYAH устарел в этом отношении (см. Http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101, ищите «Присоединиться к Num») – yatima2975

ответ

9

Изменить тип подписи для:

bmiCalc :: (RealFloat a, Show a) => a -> a -> String 

Потому что вы хотите использовать функцию-член show, от Show класса типов; но вы не указали это в ограничении функции, и ghci не имеет никакого способа сделать вывод, что это правильно.

+0

Забавно, что я пытался это сделать раньше и это не сработало ... это как-то теперь .. спасибо в любом случае! –

+5

Самый простой выход, когда у вас есть такие ошибки, - удалить подпись типа, перезагрузить файл в ghci и ввести ': t bmiCalc'. Вот как я добавляю все подписи своего типа, в конце. – mhitza

+0

приятный отзыв спасибо большое! –

2

RealFloat не является видимым типом. Вам нужно будет добавить ограничение на шоу.