Средства доступа к записям Haskell, совместно используемые разными конструкторами одного и того же типа данных

Основной вопрос о записях Haskell. Если я определяю этот тип данных,

data Pet = Dog { name :: String } | Cat { name :: String } deriving (Show)                           

следующие работы:

main = do                                                                                            
  let d = Dog { name = "Spot" }                                                                      
      c = Cat { name = "Morris" }                                                                    
  putStrLn $ name d                                                                                  
  putStrLn $ name c                                                                                  

Но если я сделаю это,

data Pet = Dog { name :: String } | Cat { name :: Integer } deriving (Show)                          

Я получу эту ошибку: Multiple declarations of 'name'.

Я думаю, что интуитивно понимаю, почему это должно быть так, поскольку тип name в первом случае — это просто Pet -> String независимо от используемого конструктора. Но я не припоминаю, чтобы встречал это правило о функциях доступа к записям ни в одной из книг по Haskell, которые я читал. Может ли кто-нибудь дать более подробное объяснение поведения, которое я вижу выше?


person dan    schedule 03.01.2014    source источник


Ответы (1)


Из отчета Haskell '98:

Объявление данных может использовать одну и ту же метку поля в нескольких конструкторах, если тип поля одинаков во всех случаях после раскрытия синонима типа. Метка не может использоваться более чем одним типом в области действия. Имена полей разделяют пространство имен верхнего уровня с обычными переменными и методами класса и не должны конфликтовать с другими именами верхнего уровня в области видимости.

Я не думаю, что есть что-то более глубокое. Как вы сказали, результирующий метод доступа к полю в любом случае имеет тип Pet -> String, поэтому полномочия, которые будут приняты, позволяют вам повторно использовать одно и то же имя поля в разных конструкторах.

person shang    schedule 03.01.2014