gpt4 book ai didi

scala - Haskell : ".... there is no single type that contains both 2 and ' b'. 的温和介绍“我不能制作这样的类型吗?

转载 作者:行者123 更新时间:2023-12-04 15:52:57 25 4
gpt4 key购买 nike

我目前正在学习 Haskell,所以这里有一个初学者的问题:

是什么意思单型在下面的文字中?

单一类型是一个特殊的 Haskell 术语吗?这是否意味着原子类型?

或者这是否意味着我永远无法在 Haskell 中列出我可以同时放入 1 的列表和 'c' ?

我在想一个类型是一组值。

所以我无法定义包含 Char 的类型s 和 Int年代?

代数数据类型呢?

类似:data IntOrChar = In Int | Ch Char ? (我想这应该可行,但我很困惑作者这句话的意思。)

顺便说一句,这是在 Haskell 中制作列表的唯一方法,我可以将两者都放入 IntsChars ?还是有更棘手的方法?

一个 Scala 类比:在 Scala 中,可以将隐式转换编写为同时表示 Int 的类型。 s 和 Char s (如 IntOrChar ),然后可以无缝地放置 Int s 和 Char转入 List[IntOrChar] ,这对 Haskell 来说是不可能的吗?我是否总是必须明确包装每个 IntChar进入 IntOrChar如果我想将它们放入 IntOrChar 的列表中?

来自 Gentle Intro to Haskell :

Haskell also incorporates polymorphic types---types that are universally quantified in some way over all types. Polymorphic type expressions essentially describe families of types. For example, (forall a)[a] is the family of types consisting of, for every type a, the type of lists of a. Lists of integers (e.g. [1,2,3]), lists of characters (['a','b','c']), even lists of lists of integers, etc., are all members of this family. (Note, however, that [2,'b'] is not a valid example, since there is no single type that contains both 2 and 'b'.)

最佳答案

简短的回答。

在 Haskell 中没有隐式转换。也没有联合类型 - 只有不相交的联合(它们是代数数据类型)。所以你只能写:

someList :: [IntOrChar]
someList = [In 1, Ch 'c']

更长,当然不是温和的答案。

注意:这是一种很少使用的技术。如果您需要它,您可能会使您的 API 过于复杂。

然而,存在类型。
{-# LANGUAGE ExistentialQuantification, RankNTypes #-}
class IntOrChar a where
intOrChar :: a -> Either Int Char

instance IntOrChar Int where
intOrChar = Left

instance IntOrChar Char where
intOrChar = Right

data List = Nil
| forall a. (IntOrChar a) => Cons a List

someList :: List
someList = (1 :: Int) `Cons` ('c' `Cons` Nil)

这里我创建了一个类型类 IntOrChar只有功能 intOrChar .这样你就可以转换任何类型的 forall a. (IntOrChar a) => aEither Int Char .

还有一种特殊的列表,它在其第二个构造函数中使用存在类型。
这里类型变量 a在构造函数范围内绑定(bind)(与 forall )。因此每次
您使用 Cons你可以传递任何类型的 forall a. (IntOrChar a) => a作为第一个论点。因此,在销毁(即模式匹配)期间,第一个参数将
还是 forall a. (IntOrChar a) => a .您唯一能做的就是传递它或调用 intOrChar并将其转换为 Either Int Char .
withHead :: (forall a. (IntOrChar a) => a -> b) -> List -> Maybe b
withHead f Nil = Nothing
withHead f (Cons x _) = Just (f x)

intOrCharToString :: (IntOrChar a) => a -> String
intOrCharToString x =
case intOrChar of
Left i -> show i
Right c -> show c

someListHeadString :: Maybe String
someListHeadString = withHead intOrCharToString someList

再次注意你不能写
{- Wont compile
safeHead :: IntOrChar a => List -> Maybe a
safeHead Nil = Nothing
safeHead (Cons x _) = Just x
-}

-- This will
safeHead2 :: List -> Maybe (Either Int Char)
safeHead2 Nil = Nothing
safeHead2 (Cons x _) = Just (intOrChar x)
safeHead将无法工作,因为您想要 IntOrChar a => Maybe a 的类型与 a绑定(bind)在 safeHead范围和 Just x将具有 IntOrChar a1 => Maybe a1 的类型与 a1绑定(bind)在 Cons范围。

关于scala - Haskell : ".... there is no single type that contains both 2 and ' b'. 的温和介绍“我不能制作这样的类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22728974/

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