簡體   English   中英

使用類創建兩個有限集

[英]Creating two finite sets using a class

我為有限集定義了一個類,如下所示:

class FiniteSet a where
elements :: [a]

現在,我要創建兩個字符集,假設A = {'a','c','f'}和B = {'x','y'}。 我該怎么做? 但是,我嘗試按以下方式創建Char實例,但是之后呢?

instance FiniteSet Char where
elements = []

謝謝。

你可能只想說

type FiniteSet a = [a]
a = ['a', 'c', 'f'] -- = "acf"
b = ['x', 'y']      -- = "xy"

或可能

newtype FiniteSet a = FiniteSet { elements :: [a] }
a = FiniteSet ['a', 'c', 'f']
b = FiniteSet ['x', 'y']

如果要確保不要混淆FiniteSet和列表。

好的,我會嘗試就此發表一些意見。

您應該問自己的第一個問題是我需要class嗎? (我在這里不這么認為,但讓我們繼續吧)。


您選擇的方式告訴我們:

當類型aFinitSet的實例時,我們可以得到一個元素列表[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..]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM