我已经为有限集定义了一个类,如下所示:
class FiniteSet a where
elements :: [a]
现在,我想创建两个字符集,让我们说A = {' a',' c'' f'}和B = {' x',' y'}。我该怎么办?但是,我尝试按如下方式创建一个Char实例,但之后呢?
instance FiniteSet Char where
elements = []
感谢。
答案 0 :(得分:0)
好的,我会尽量给你一些关于我的意见的提示。
您应该问自己的第一个问题是我需要class
吗? (我不这么认为,但让我们继续吧)。
您选择这样做的方式告诉我们:
当类型a
是FinitSet
的实例时,我们可以返回一个元素列表[a]
,这是的一个输入不是类型的值 - 我怀疑你想要的是什么。
也许你认为有这样的事情:
class FiniteSet a where
elements :: a -> [a]
在这里你可以得到一些给定值的列表,但这看起来很奇怪不是吗?给定一个值你会得到更多相同的值吗?那么也许你得到的元素类型应该与实例类型不同?
class FiniteSet i e where
elements :: i -> [e]
但现在你肯定会遇到这样的情况:你想知道为什么i
并不暗示e
,你会搜索并查找和找到功能依赖和东西,它会更复杂的是第二个。
所以我觉得你并不是那么想。
也许你想要捕捉到它的本质 - 就像:
class FiniteSet i e where
count :: i -> Int
empty :: i
isElem :: i -> e -> Bool
addElem :: i -> e -> i
通过这种方式你最终会得到这样的结果:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
module FinSet where
class FiniteSet i e | i -> e where
count :: i -> Int
empty :: i
isElem :: e -> i -> Bool
addElem :: i -> e -> i
instance Eq a => FiniteSet [a] a where
count xs = length xs
empty = []
isElem x xs = x `elem` xs
addElem xs x = if x `elem` xs then xs else x:xs
看看你如何仍然需要很多扩展只是为了一个简单的列表定义一个实例,它只使用你已经在列表中的内容?
当我告诉你我认为你不需要/想要一个课时,这就是我的意思,因为你似乎只想要一个类型同义词/ newtype
列表
无论如何,这将为你提供一些构建集合的方法:
λ> let fin = (empty `addElem` 'a' `addElem` 'b' `addElem` 'c')
λ> count fin
3
λ> 'b' `isElem` fin
True
λ> 'd' `isElem` fin
False
λ> fin `addElem` 'a'
"cba"
问题当然是你不会得到任何甚至是有限的保证(这只是这个实例的列表)并且说实话我没有看到救援我们的方法这种情况现在:
λ> let nats = foldr (flip addElem) empty [0..]