Отладка: не удалось сопоставить ожидаемый тип ‘GHC.Типы.Bool’ с фактическим типом ‘Bool’

#debugging #haskell #lambda #case #lambda-calculus

#отладка #haskell #лямбда #случай #лямбда-исчисление

Вопрос:

Я пытаюсь разрешить следующее упражнение Haskell:

Определите функцию exists::(N-> Bool)-> N->Bool , которая получает предикат p и натуральное число n и возвращает значение True, если между O и n есть какое-либо число, для которого значение p равно true. Примеры:

 exists pair three = True
exists isGreaterThanZero O = False
 

Этот код идет перед моей функцией exists:

 {-#LANGUAGE GADTs #-}
{-# OPTIONS_GHC -fno-warn-tabs #-}
{-# OPTIONS_GHC -fno-warn-missing-methods #-}

module Naturales where

import Prelude(Show)

data Bool where {   False :: Bool; 
                    True :: Bool
                } deriving Show

{- Data Type of Natural Numbers -}
data N where { O :: N ; 
               S :: N -> N 
            } deriving Show
    
    zero:: N
    zero= O
    
    one:: N
    one = S O
    
    two :: N
    two = S one 
    
    three :: N
    three = S two 
    
    four :: N
    four = S three
    ...
 

Вот как я запрограммировал запрошенную функцию с именем exists, но когда я пытаюсь скомпилировать код .hs, он
говорит

 exists:: (N->Bool)->N->Bool
exists = p -> x -> case x of {
            O -> p O;
            (S y) -> if p (S y) then True else existe p y; {- Line 288 -}
        }


    • Couldn't match expected typeGHC.Types.Bool
                  with actual typeBool
      NB: ‘Bool’ is defined at EstudiandoRecursion.hs:(9,1)-(11,47)
          ‘GHC.Types.Bool’
            is defined inGHC.Typesin package ‘ghc-prim-0.5.3’
    • In the expression: p (S y)
      In the expression: if p (S y) then True else existe p y
      In a case alternative:
          (S y) -> if p (S y) then True else existe p y
    |
288 |                         (S y) -> if p (S y) then True else existe p y;     | 
 

Я полагаю, что логика моей функции существует, она правильная, но, возможно, я допустил синтаксическую ошибку при написании кода.

Комментарии:

1. Похоже, вы определили Bool тип в своем коде и, следовательно, больше не ссылаетесь на Bool of GHC.Types.Bool .

2. @WillemVanOnsem, я обновил описание своего вопроса, добавив свой код заголовка, который находится перед функцией exists

3. Well if ... ожидает a Bool встроенного типа, поэтому True / False from вашего типа будет недостаточно .

Ответ №1:

Вы переопределили стандартный Bool тип. Haskell не знает, что ваш собственный переопределенный тип на самом деле совпадает со стандартным, поэтому он рассматривает их как два отдельных типа: Bool (ваш) и GHC.Types.Bool (стандартный).

if cond then t else e Выражение работает только со стандартным Bool типом, а не с вашим пользовательским. Следовательно, вы не можете использовать его в

 if p (S y) then True else exists p y
 

поскольку p (S y) возвращает ваш собственный пользовательский Bool . Вместо этого рассмотрим

 case p (S y) of
   True  -> True
   False -> exists p y
 

который, в отличие if от, должен работать, выбирая правильные True конструкторы и False конструкторы из вашего нового типа. Вы можете использовать case .. of { .. ; ... } , если предпочитаете фигурные скобки и точки с запятой.

Ответ №2:

Вы используете if … then … else … выражение. Для этого требуется, чтобы условие имело тип Bool , и это встроенный Bool , поэтому определения вашего собственного Bool типа будет недостаточно.

Однако достаточно работать с case … of … предложением и, следовательно, сопоставлять шаблоны в ваших True False конструкторах / data:

 exists:: (N -> Bool) -> N -> Bool
exists = p -> x -> case x of {
            O -> p O;
            (S y) -> case p (S y) of
                True -> True
                _ -> exists p y
        }