проверка свойства класса haskell - PullRequest
2 голосов
/ 17 марта 2011

Я хотел бы иметь функцию, которая проверяет свойство экземпляра класса:

class ListWithAtLeastOneElement a where
   list :: [a]
   check :: Bool
   check = (length list) >= 1

, но я получаю эту ошибку при компиляции в GHC: «Метод класса« check »не упоминает ни одного типапеременные класса ListWithAtLeastOneElement a При проверке метода класса: check :: Bool В объявлении класса для 'ListWithAtLeastOneElement' "

Есть ли лучший способ сделать то, что я хочу, или способ заставить это скомпилироватьв GHC?

Ответы [ 3 ]

3 голосов
/ 17 марта 2011

Вы, кажется, думаете, что класс в Haskell подобен классу в ОО-языке.Это неправда.Вы должны использовать тип данных или новый тип или синоним типа.

newtype NonemptyList a = List1 [a]

fromList :: [a] -> Maybe (NonemptyList a)
fromList []       = Nothing
fromList xs@(_:_) = Just $ List1 xs

check :: NonemptyList a -> Bool
check (List1 xs) = length xs >= 1
2 голосов
/ 17 марта 2011

Как сказал jmg, это не допустимый Haskell, поэтому хорошо, что GHC его не компилирует! Если вы, очевидно, привыкли к Java, вам следует подумать о классах типов Haskell, таких как интерфейс Java. Если это не поможет, возможно, вам следует прочитать главу LYAH о занятиях .

Похоже, вы хотите использовать тип данных со списком, который никогда не может быть нулевым. Вам не нужно проверять для такого свойства, вы можете статически убедиться в этом, используя данные тип, который никогда не может быть пустым:

-- Notice this data type can never have zero 'a' values!
data NonEmptyList a = NEL a (NonEmptyList a) | Singleton a

-- We can define basic operators for this, just like list has
-- You can't pattern match with them, but there are work-arounds for that if you want to ask
(.:) = NEL  -- concatenate non-empty lists

nelHead :: NonEmptyList a -> a 
nelHead (NEL a _) = a
nelHead (Singleton a) = a

nelTail :: NonEmptyList a -> Maybe (NonEmptyList a)
nelTail (NEL _ b) = Just b
nelTail _ = Nothing

nelTake :: Int -> NonEmptyList a -> NonEmptyList a
nelTake 1 (NEL a _) = Singleton a
nelTake 1 (Singleton a) = Singleton a
nelTake n (NEL a rest) = a .: nelTake (n-1) rest

nelDrop :: Int -> NonEmptyList a -> NonEmptyList a
nelDrop _ (Singleton _) = error "Perhaps I should have used the 'maybe' type"
nelDrop 1 (NEL a r) = r
nelDrop n (NEL a r) = nelDrop (n-1) r

И так далее, и тому подобное. Стоит отметить, что nelTake и nelDrop являются частичными, но nelHead является полным, забавно, поскольку это противоположно обычным спискам.

1 голос
/ 17 марта 2011

Вам нужно сделать проверку функцией

check :: [a] -> Bool

Тем не менее, вам лучше использовать тип данных для непустых списков, а некласс, классы в Haskell не служат той же цели, что и классы в объектно-ориентированных языках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...