主頁 > 資料庫 > Haskell中多型型別的真實型別是隱式普遍量化的型別嗎?

Haskell中多型型別的真實型別是隱式普遍量化的型別嗎?

2022-03-22 12:07:58 資料庫

我試圖澄清一些 Haskell 概念,并想知道是否有人可以提供幫助。

通過資料宣告定義型別時,例如:

資料 DatumType ab = 基準 ab

我一直想知道型別是DatumType還是隱含 forall a. DatumType a b的。

因為確實有ExplicitForAll

λ> :set -XExplicitForAll
λ> :k forall a. Maybe a
forall a. Maybe a :: *

λ> :k forall a b . DatumType a b
forall a b . DatumType a b :: *

λ> :k DatumType
DatumType :: * -> * -> *

我們可以看到種類forall a b. DatumType a bproper type i.e. *

然而 DatumType 本身只是一個型別建構式。

因此,這意味著諸如 [a] 之類的多型型別是 TYPE(即 *),并且該型別的全名是forall a. [a]

換句話說,我要確認的是,haskell 中的多型型別宣告始終采用縮寫形式,并且完整的型別名稱始終帶有隱式forall a. ....

也就是說, indata Mytype a型別不僅MytypeMytype a,而且forall a. Mytype a, whileMytype是型別建構式。

這種解釋正確嗎?

EDIT1(在@Daniel Wagner 回答之后)

我想我會編輯這個問題,以解釋所有澄清的東西來自哪里。假設在學習和試驗型別類時,我對實體 Eq (a,b) 感到困惑。為什么不實體化 Eq(,),答案不僅僅是因為在實作中需要參考型別變數。Eq 只能在正確的型別上定義,任何可能的對實際上都是一種型別,一種多型型別。那么問題來了,但是當我們寫 data (,) ab = (,) ab 時,我們在定義什么。我是在定義 (,) 還是 forall a b。(一,乙)。

Edit2(按照@Ben 回答)

One of the material that drove my formalisation together with the :set -XExplicitForAll experiment above is the following statement taken from here A Gentle Introduction to Haskell, Version 98 - 2 Values, Types, and Other Goodies

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.

uj5u.com熱心網友回復:

翻譯成英文的定義data DatumType a b = Datum a b是這樣的:

假設有一個名為的新型別建構式DatumType和一個名為的新資料建構式Datum,這樣對于所有型別aand bDatum應用于 type 的值,a并且 type 的值產生 typeb的值DatumType a b

我一直想知道型別是DatumType還是隱含 forall a. DatumType a b的。

我認為理解這里的障礙是術語“型別”可以有兩種不同的含義,具體取決于背景關系:

  1. 型別是存在于型別級別的任何物體
  2. 型別具體是那些可以作為術語型別的型別級物體任何類似的東西Type(也稱為*),并且只有這樣的東西

這兩個定義的出現基本上是因為我們使用短語“type of”來描述術語級別的事物與型別級別的事物之間的關系——因此將不能參與該關系的事物包含在“型別”。然而,型別運算式中存在很多不能直接參與這種關系的東西,我們想談論它們,而不必一直使用像“型別級物體”這樣的笨拙短語。作為一個社區,我們似乎沒有想出比在不同時間在這兩種意義上使用“型別”更好的解決方案,并希望從背景關系中清楚。

所以很明顯這DatumType不是定義2的型別;它需要應用于兩個型別引數才能在術語級別產生某種型別。如果這就是我們的想法,那么我可以理解為什么您會傾向于認為資料宣告定義的“型別”是forall a b. DatumType a b.

但是,我認為這可能是一種令人困惑的思考方式。就其本身forall a b. DatumType a b而言,是可以在所有型別的表格中使用的術語型別DatumType _ _這種型別的唯一值是Datum undefined undefined. 相反forall a b,當您看到時,通常會更遠DatumType a b例如,Datum建構式本身的型別(如果您使用 GADT 語法定義它,您將撰寫它)可以寫為Datum :: forall a b. a -> b -> DatumType a b.

所以說“資料宣告定義的型別forall a b. DatumType a b很奇怪。資料宣告定義了一整套型別,其中型別forall a b. DatumType a b是一個極其有限(而且相當無用)的例子。相反,我會說“對于所有型別ab,資料宣告定義了一個型別DatumType a b";所涉及的"for all"概念的范圍比你forall在單個型別運算式中用關鍵字表達的范圍更廣,所以我把它從正式的型別運算式中移到了英文描述中。

當然,如果我們專注于“型別”的定義 1,那么事情就更容易解釋了。資料宣告只是DatumType用 kind定義了一個型別* -> * -> *

這就引出了一個問題:哪種觀點是正確的?

也許令人不滿意的是,這兩種觀點之間沒有什么有趣的事情發生。這兩件事都發生了:我們得到了一個新的型別建構式DatumType,它有 kind * -> * -> *,并且對于所有型別a,并且b DatumType a b是某些術語的型別。這就是善意的* -> * -> * 意思只有當您嘗試識別“型別”而沒有意識到術語型別在這兩種意義上都經常使用時,才會出現困境所以如果您不清楚自己在使用哪種意義上,可能會犯錯。

Some contexts say that things which don't have kind * are not types, and therefore DatumType is not really a type. Others talk about DatumType as a type. However that is purely a difference in what terminology we choose to use; either way DatumType :: * -> * -> * is a thing that exists, and it functions the same in either viewpoint. Getting hung up on whether a particular type-level entity is or is not a type is not a question of how things really work, it's just a question of English language usage.

So to come back to some of your more specific questions:

Hence this would mean that polymorphic type such as [a] are TYPE (i.e. *) and that the full name of the type is forall a. [a]

In other word, what i am after is to confirm that type declaration in haskell for polymorphic type are always in an abbreviated form, and that the full type name is always with an implicit forall a. ....

As I mentioned, I think this is not quite correct. Yes, [] at the type level needs a parameter to result in a type-of-terms; [] :: * -> *. So by definition 2, [] is not a type. However it's not really right to say that the full list type is "really" forall a. [a], as that is a specific type expression for universally polymorphic lists (which can only be the type of empty lists, or of lists full of bottom values, or a list that is the bottom value). In particular, [True, False] is a member of the type [Bool], and is not a member of the type forall a. [a].

Rather [] is just a type-level-entity of kind * -> *. whether you call that a type or not is up to you. Either way it is not the type of any terms, and either way it is a valid thing you can use in type expressions (provided they kind-check).

That is, in data Mytype a the type is not Mytype neither just Mytype a, but forall a. Mytype a, while Mytype is a type constructor.

It is true that Mytype is a type constructor. (In either definition of the word "type"; even if we're happy to call all type-level entities types, "type constructor" is still a specific category, and it's a good term to have because whether something is a "type constructor" cannot be determined just by looking at its kind, in the same way that you can't determine whether something is a data constructor just by looking at its type)

It is true that Mytype a on its own is not meaningful; it has to be used in a scope where a type variable a is in scope.

It is not true that forall a. Mytype a is the right way to think of "the type defined by data Mytype a. For any type a Mytype a is a type; forall a. Mytype a is a specific type expression that does not include most of the types we can form with the Mytype type constructor.

So any time you want to use Mytype a there will be a forall somewhere (either explicit or implicit). But it will usually be further out than immediately enclosing Mytype a; something like someFunc :: forall a. a -> Bool -> MyType a.


The OP left a comment on the other answer which I think it will be insightful to address:

I think I will edit the question, to explain where the all thingy of clarification is coming from. Let’s just say that while learning and experimenting with type classes, I was confused about instance Eq (a,b). Why not instance Eq (,), and the answer is not just because one need to refer to the type variable in the implementation. Eq can only be defined on a proper type, and any possible pair is actually a type, a polymorphic type. Then came the question, but what are we defining when we write data (,) a b = (,) a b . Am I defining (,) or forall a b. (a,b).

Keep in mind that making a type an instance of Eq is intended to mean that you can compare values of that type for equality.

When you say instance Eq (a, b) it really means instance forall a b. Eq (a, b); in English "for all types a and b, the type (a, b) is a member of the class Eq. It means you can pick any two types you like, apply the (,) type constructor to them, and the resulting type will be something use values you can compare for equality. (This is of course not actually true, the instance we really use is more like instance forall a b. (Eq a, Eq b) => Eq (a, b), because we need Eq a and Eq b)

instance Eq (,) is wrong because it is saying "the type constructor (,) is a member of the class Eq". "Values of (,) can be compared for equality" makes no sense, as (,) is not the kind of thing that can have values.

But (,) is still a thing that exists! And it's straightforwardly the thing defined by data (,) a b = (,) a b. It's just a thing with kind * -> * -> *, which is not the kind of thing we can make an Eq instance for. The phrase "Eq can only be defined on a proper type" is using the definition of "type" that only includes things with kind *, but remember "not being a proper type" by this definition does not mean "isn't a real thing", it just means we're choosing (in that particular sentence, at least) to use the word "type" with a narrow meaning. The class Eq is defined to have as members things with kind *, that's all. Other classes can be defined to have things with different kinds as members; if they have members of kind * -> * -> * then (,) on its own can be an instance of those classes. Have a look at the list of instances for Bifunctor, for example. The fact that the Eq instance has to be Eq (a, b) and not Eq (,) does not imply that (,) isn't "really" a valid entity that exists at the type level.

uj5u.com熱心網友回復:

宣言

data DatumType a b = Datum a b

宣告一種新型別 , DatumTypekind * -> * -> *它還宣告了一個Datum型別為 的新術語forall a b. a -> b -> DatumType a b

在正常情況下,型別簽名確實隱式地普遍量化了它們在頂層提到的所有型別變數。但是資料宣告不是型別簽名,因此您的問題的某些部分沒有意義。

在打開擴展的情況下,型別變數也可能是單態的,而不是普遍量化的。例如,

{-# LANGUAGE ScopedTypeVariables #-}

foo :: forall a. Monoid a => a -> a
foo x = mconcat xs where
    xs :: [a]
    xs = [x, mempty, x]

在此代碼片段中,所有量詞都已明確。在 where 塊內,xs具有單態 type [a], wherea是由封閉型別范圍系結的型別變數,如果您插入了額外的量詞,則代碼將無法編譯:

foo :: forall a. Monoid a => a -> a
foo x = mconcat xs where
    xs :: forall a. [a]
    xs = [x, mempty, x]
    -- type error: can't match type a and type a0, whoops

有了這些資訊,希望你的每一個陳述的真實狀態更清楚,但讓我們一次過一遍:

我一直想知道型別是DatumType還是隱含 forall a. DatumType a b的。

無法回答。什么型別?DatumType都是forall a. DatumType a b合法的型別級運算式。

這意味著像 [a] 這樣的多型型別是 TYPE 并且型別的全名是forall a. [a]

有時。量詞的插入不是本地程序,而是整個型別簽名的全域程序。它們隱式地浮動到頂層。所以,這是兩種不同的型別:

-- these are all the same with ScopedTypeVariables off
forall a. [a] -> ()
forall a. ([a] -> ())
[a] -> ()

-- this is a different type from the ones above
(forall a. [a]) -> ()

So if, in normal, un-extended Haskell, you wrote the type signature x :: [a], then [a] would indeed be shorthand for forall a. [a]; but if you wrote the signature f :: [a] -> (), then [a] would not be shorthand for forall a. [a], because the forall has to be floated out from being on an argument to the arrow to being on the entire type.

In other word, what i am after is to confirm that type declaration in haskell for polymorphic type are always in an abbreviated form, and that the full type name is always with an implicit forall a. ....

Yes.

That is, in data Mytype a the type is not Mytype neither just Mytype a, but forall a. Mytype a, ...

Category error. data Mytype a is not a type signature, so there is no the type. If I were to single out a type to call "the type" from such a declaration, it would be Mytype alone, as that is the only type that gets created by the declaration.

...while Mytype is a type constructor.

Yes.

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/446077.html

標籤:haskell

上一篇:Haskell-無法匹配型別

下一篇:當使用像“棱鏡”這樣的光學型別時,在“DerivingVia”期間無法強制

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more