gpt4 book ai didi

Haskell:带参数的类型(编辑:又名依赖类型)

转载 作者:行者123 更新时间:2023-12-04 05:18:21 27 4
gpt4 key购买 nike

我刚刚开始在 Haskell 中定义我自己的类型,我在第 3 节中找到了示例
http://www.haskell.org/haskellwiki/Type
关于代表卡有用。有些事情我想做,但我不知道如何实现。我将尝试使用卡片类比来解释。

我想处理不同的卡片系列。假设我们修复了卡片总是具有 CardValue 和 Suit,但除了标准系列之外,我还想允许一副有第五套花色“Rubies”的套牌。我希望能够做一些事情,比如采取 Kind1 和 Kind2 并定义一种卡片 Kind3,它尽可能适合 Kind1 和 Kind2 的西装的并集,并作为 cardvalies 来自 Kind1 的西装集。我还想编写一个程序,用户可以输入花色名称等,然后我们可以用她输入的卡片类型执行一些标准的卡片操作。我不想做的只是写出有限数量的不同数据类型,因为我事先不知道我所有不同类型的卡片是什么。

我可以想象一个包含大量列表和大量检查的解决方案,以查看事物是列表的元素,但我认为编写它会是一场噩梦,而且效率很低。

让我写一些无效的伪代码,但可能比我上面的描述更好地了解我想要做什么。

-- this isn't real code!

type Suit = [String]
type CardValue = [String]

data (Card s v) = (Card s v) {suit :: (s :: Suit), value :: (v :: CardValue)}

usualSuit :: Suit
usualSuit = ["Club","Diamond","Heart","Spade"]

flowerSuit :: Suit
flowerSuit = ["Rose","Daisy","Poppy"]

当然我知道这是无稽之谈,我猜这违背了在编译时定义的所有类型的原则(我可以看到这是一个很好的原则)。

谁能告诉我:
  • 有没有办法做我所描述的事情?
  • 有没有更好的方法来实现同样的目标?

  • 我也对要阅读的链接/关键字感兴趣,但请注意,我不知道太多编程术语,甚至不了解 Haskell。

    我确实想使用 Haskell 来做到这一点——惰性求值和无限列表对我非常有用,而且我已经编写了代码来做事情。

    我试过谷歌搜索并浏览了一些 Haskell 教程(我仍然是初学者!)但没有找到任何有用的东西。这可能是因为我不知道要搜索什么词。

    谢谢

    编辑 : 我担心我没有解释我想要做好的事情。这是一些编译时没有错误的真正代码,带有解释我想要它做什么的注释。
    import Data.List

    type Suit = String
    type Value = Integer
    type ListOfSuits = [Suit]
    type ListOfValues = [Value]

    data Deck = Deck {listofsuits :: ListOfSuits, listofvalues :: ListOfValues } deriving (Show)

    sillyDeck :: Integer -> Deck
    -- This is some function. For example, we might have
    sillyDeck n = Deck ["Heart","Spade"] [1..n]
    -- Note that this defines infinitely many different decks

    -- How should I define a card in sillyDeck n? One option is
    data Card = Card {suit :: Suit, value :: Value } deriving (Show)
    -- but this doesn't reference the deck I'm using. I could try
    data Card2 = Card2 {suit2 :: Suit, value2 :: Value, deck2 :: Deck } deriving (Show)
    -- but then
    cardInWrongDeck :: Card2
    cardInWrongDeck = Card2 "Cheese" 999 (sillyDeck 3)
    -- is valid, when I'd hope for something like a type error.
    -- Of course, I could write a function to check that each card is in the
    -- deck it claims to be, and apply it regularly, but that's a horrible solution.

    -- Is there a better way to do this?

    希望这也能解释我的标题:我想定义一个类型(CardOfType 套牌),它以某种 Deck 类型的套牌作为参数。我想你不能这样做,但我不知道。

    我想做的事情(基本上,有一组对象,每个对象都是一组对象)似乎是一件基本的事情——我敢打赌人们以前遇到过类似的问题,我希望有一些很好的结构方式解决这个我不知道的问题。

    编辑 2:基于 Philip JF 将我指向 GADT(= 广义代数数据类型)并进行了一些阅读,我意识到我正在寻找的东西称为“依赖类型”。所以我原来的标题“带参数的类型”听起来并不那么 absurd 。似乎这些在 Haskell 中不存在。我找到了谈论模拟它们的论文,并阅读了显然支持类型函数的Ωmega。我仍然不知道是否存在一种将值作为参数的类型的语言。

    最佳答案

    如果您愿意使用高级功能,Haskell 的类型系统几乎可以做任何事情,但是我不鼓励在学习 Haskell 时尽早使用其中的大部分。在你的情况下,我可能会像这样建模

    data Card s v = Card {suit :: s, value :: v}

    然后定义一套西装
    data UsualSuit = Club | Diamond | Heart | Spade deriving
    data FlowerSuit = Rose | Daisy | Poppy

    这可以满足您的大部分需求。例如,很容易定义复合套装,如
    data Rubies = Rubies
    type UsualOrRubies = Either UsualSuit Rubies

    我认为这完全解决了您在静态情况下的需求。当您有一个动态进入西装的用户时,事情会变得更加复杂。一种选择是“字符串类型”
    type StringySuit = String

    你可以使用 GADTs 做一些事情但是除非你给出一个更大的例子来说明你的问题是什么,否则我不知道 String 的问题是什么。基于的解决方案将是。实际上可以使用 GADT 有效地“在运行时创建类型”,但是对于初学者来说可能会感到困惑。

    关于Haskell:带参数的类型(编辑:又名依赖类型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13963178/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com