У меня есть этот пример кода:Почему компилятор не принимает возвращаемый Int8 как «Real c»?
module Main where
import Data.Int
import Data.Text
data JavaValue = JavaString Text
| JavaByte Int8
| JavaShort Int16
| JavaInt Int32
| JavaLong Int64
| JavaFloat Float
| JavaDouble Double
| JavaChar Char
| JavaBool Bool
| ArrayValue [JavaValue]
| JavaNull deriving (Eq)
getnumberfromvalue :: Real c => JavaValue -> Maybe c
getnumberfromvalue (JavaByte n) =Just n
getnumberfromvalue (JavaShort n) =Just n
getnumberfromvalue (JavaInt n) =Just n
getnumberfromvalue (JavaLong n) =Just n
getnumberfromvalue (JavaFloat n) =Just n
getnumberfromvalue (JavaDouble n) =Just n
getnumberfromvalue (JavaChar n) =Just $ fromEnum n
getnumberfromvalue _ = Nothing
Этот код не компилируется с этой ошибкой:
test.hs:25:34: error:
• Couldn't match type ‘c’ with ‘Int’ ‘c’ is a rigid type variable bound by the type signature for: getnumberfromvalue :: forall c. Real c => JavaValue -> Maybe c at test.hs:18:23 Expected type: Maybe c Actual type: Maybe Int • In the expression: Just $ fromEnum n In an equation for ‘getnumberfromvalue’: getnumberfromvalue (JavaChar n) = Just $ fromEnum n • Relevant bindings include getnumberfromvalue :: JavaValue -> Maybe c (bound at test.hs:19:1)
Я не понимаю, почему, так как Int(8,16,32,64)
и Float
и Double
все Real
почему он говорит, что он не может соответствовать Int
с c
? !!
Вышеупомянутый код - это лишь небольшая часть компилятора java, который я создаю для университетского проекта, getnumberfromvalue
- это просто функция полезности, JavaValue
- представлять собой буквальный Java.
Я знаю о fromIntegral
и realToFrac
, и я не думаю, что могу использовать их здесь.
Я видел this вопрос, но ответ использует GADT и ExistentialQuantification, похоже, только для типов, я не думаю, что хочу использовать его для этой простой проблемы, даже без GADT нет способа, t включает определение тривиального типа данных? ,
Это не так, как полиморфизм работает Haskell. Классы типов не являются подтипированием. Переменные типа выбираются * вызывающим * функцией, а не самой функцией. Есть ли какой-то вопрос, который охватывает это действительно хорошо? – Carl
Редактировать: совершенно неверное утверждение, сохраненное для потомков, следует - О, и, для чего он стоит, типы 'Int' и' Word' не являются экземплярами 'Real'. – Carl
@ Карл Да, они есть. – jpath