如何在Haskell中表示这种类型

时间:2017-03-21 19:45:51

标签: haskell types

如何表示包含1个字符串的列表和另一个包含最多3个字符串的列表。

喜欢这个:

osztaly = [("András", ["mákos", "meggyes", "almás"]), ("Joli", ["túrós"]), ("Anna", ["almás", "almás"]), ("Tamás", []), ("Mari", ["almás", "meggyes"]), ("Vera", [])]

1 个答案:

答案 0 :(得分:7)

如果你只需要3号尺寸:

{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveTraversable #-}
data ListUpTo3 a
    = Zero
    | One a
    | Two a a
    | Three a a a
    deriving (Functor, Foldable, Traversable)

FunctorFoldableTraversable个实例可以恢复内置列表可用的许多(但不是全部)便捷功能。

如果您可能需要其他大小而不是max-3,您可以对此进行概括,但它需要更多的类型级编程,这为类型的实现者和类型的用户增加了重要的程序员工作量。 / p>

就个人而言,我可能不会尝试在类型级别捕获此约束。然后没有编译器检查max-length-3位;但它的实现和使用也更简单。您可以在网络的其他地方通过关键字" smart constructor"了解更多有关此想法的信息。

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- N.B. we do not export the value constructor, only the type constructor
module UpTo3 (ListUpTo3, fromList, toList) where

newtype ListUpTo3 a = ListUpTo3 [a] deriving (Functor, Foldable, Traversable)

fromList :: [a] -> Maybe (ListUpTo3 a)
fromList xs = if null (drop 3 xs) then Just (ListUpTo3 xs) else Nothing

toList :: ListUpTo3 a -> [a]
toList (ListUpTo3 xs) = xs