Равенство по умолчанию для типов записей?

Я делаю это упражнение из конца главы 3 в The Purescript Book:

Напишите функцию, которая ищет запись по адресу, повторно используя существующий код в findEntry. Проверьте свою функцию в PSCi.

Я пытался:

findByAddress address = head <<< filter filterEntry
  where
    filterEntry :: Entry -> Boolean
    filterEntry entry = entry.address == address

какие ошибки с:

  No type class instance was found for

    Data.Eq.Eq { street :: String
               , city :: String  
               , state :: String 
               }                 


while applying a function eq
  of type Eq t0 => t0 -> t0 -> Boolean
  to argument entry.address
while inferring the type of eq (entry.address)
in value declaration findByAddress

Вопрос 1: Я бы подумал, что типы записей имеют функцию равенства по умолчанию, а именно, что все атрибуты записей равны. Есть один? Как мне его использовать?

Вопрос 2: На случай, если мое предположение, приведенное выше в вопросе 1, было ложным, я попробовал:

eq :: Address -> Address -> Boolean 
eq address1 address2 = address1.street == address2.street &&
                       address1.city == address2.city &&
                       address1.state == address2.state

Но это не решило проблему. Почему нет?


person Jonah    schedule 15.04.2018    source источник


Ответы (1)


bower install purescript-record-extra

pulp repl
> import Data.Record.Extra (eqRecord)

> {a:1, b:2.5} `eqRecord` {a:1, b:2.5}
true

> {a:1, b:2.5} `eqRecord` {a:1, b:3.5}
false

-- different record types cannot be compared

> {a:1, b:2.5} `eqRecord` {a:1, b:3.5, c:"abc"}
Error found:
in module $PSCI
at  line 1, column 25 - line 1, column 45

  Type of expression contains additional label c.

while checking that expression { a: 1    
                               , b: 3.5  
                               , c: "abc"
                               }         
  has type { a :: Int   
           , b :: Number
           }            
while applying a function ((eqRecord (#dict RowToList t2 t1)) (#dict EqRecord t1 t2)) { a: 1  
                                                                                      , b: 2.5
                                                                                      }       
  of type { | t0 } -> Boolean
  to argument { a: 1    
              , b: 3.5  
              , c: "abc"
              }         
in value declaration it

where t0 is an unknown type

Обновление pkg-purescript-record имеет равенство op.

> import Data.Record (equal)
> {a:1, b:2.5} `equal` {a:1, b:2.5}
true

> {a:1, b:2.5} `equal` {a:1, b:3.5}
false

> {a:1, b:2.5} `equal` {a:1, b:2.5, c:"abc"}
Error found:
in module $PSCI
at  line 1, column 22 - line 1, column 42

  Type of expression contains additional label c.

while checking that expression { a: 1    
                               , b: 2.5  
                               , c: "abc"
                               }         
  has type { a :: Int   
           , b :: Number
           }

Использование новых типов и производных экземпляров:

> newtype Address = Address {street::String, city::String}

> derive instance eqAddress :: Eq Address

> Address {street:"la Rambla", city:"Barcelona"} == Address {street:"main", city:"LA"}
false
person Gabriel Riba    schedule 15.04.2018
comment
Спасибо, Габриэль. Можете ли вы объяснить, почему моя попытка исправить в вопросе 2 не сработала? - person Jonah; 15.04.2018
comment
@Jonah Пример из Q.2 компилируется и хорошо работает, если вы даете eq имя, которое не скрывает Prelude.eq. Но Data.Record (equal) или Data.Record.Extra (eqRecord) кажутся общим равенством для записей - person Gabriel Riba; 15.04.2018
comment
@Jonah Я добавил (к тексту) производные экземпляры равенства в record newtypes. - person Gabriel Riba; 16.04.2018