簡體   English   中英

haskell數據定義錯誤 - 類型中的非法文字(使用-XDataKinds啟用)

[英]haskell data definition error - Illegal literal in type (use -XDataKinds to enable)

我正在學習哈斯克爾。 我試過的時候:

Prelude> data Binary = 0 | 1

我有:

<interactive>:2:15:
    Illegal literal in type (use -XDataKinds to enable): 0

即使我使用ghci -XDataKinds啟動ghci

我還有:

<interactive>:2:15:
    parse error in constructor in data/newtype declaration: 0

任何人都可以對此有所了解嗎?

基本上,不允許使用0和1之類的數字作為用戶定義類型的數據構造函數的名稱。 從語法上講,它們必須是以大寫字母開頭的單詞。 例如,您可以這樣做:

data Binary = O | I

(注意那些是大寫字母'o'和'i',而不是數字零和一。)

data Binary = 0 | 1 data Binary = 0 | 1不是定義數據類型的正常形式。 data定義需要數據構造函數01不是它們的合法語法,因為它們已經被用於數值文字。 這是第二條錯誤消息試圖告訴您的,並且是基本的Haskell。 數據構造函數最常用的語法是大寫單詞,所以你可能想要更像的東西

data Binary = Zero | One

注意:此消息的其余部分是您可能不需要的高級內容,但我想解釋一下為什么您收到有關-XDataKinds第一條錯誤消息。

使用DataKinds擴展, 01 確實成為不同類型的合法“類型”(稱為Nat ,實際上“kind”是這里的技術術語),用於高級類型級編程,並且還有一些擴展,它可以獲得包含它們的數據定義。

請注意,下面的示例可能不是很有用 ,我只是將它拼湊在一起以表明它是可行的。 在實踐中,除非你做的很高級,否則data Binary = Zero | One data Binary = Zero | One可能更像你想要的。

{-# LANGUAGE DataKinds, KindSignatures #-}

import GHC.TypeLits (Nat)

data Proxy (n :: Nat) = Proxy
data WeirdBinary = Zero (Proxy 0) | One (Proxy 1)

我實際上沒有能夠做的工作(雖然我只是嘗試了一會兒)是從data Binary = 0 我得到的最接近的是奇怪的東西

class (n :: Nat) /// a where

data Binary = (0 /// Bool) => ThisIsSilly

其中0仍然需要在括號內。 我認為邏輯上這個特殊形式應該沒有括號,但事實並非如此。

鑒於此,我認為通過建議有一些方法可以使擴展在該位置適合0 ,Haskell會不必要地混淆。 但是,由於解析和類型/種類檢查在GHC中是分開的階段,因此以更加用戶友好的方式捕獲它可能過於復雜,甚至可能最終意味着將來有效。

第一誤差是說,像文字值01 (或實際上"foo"[1, 2, 3] 'Z' )是無效的類型聲明

您不能聲明包含現有類型元素的新類型,因為它看起來像您嘗試使用data Binday = 0 | 1 data Binday = 0 | 1 類型只能包含另一種類型的所有成員(這就是為什么在類型表達式中包含其他類型而不是值的原因 )。

DataKinds擴展引入了新的類型形式(我不會在這里介紹),這意味着文字值可以出現在某些位置的類型聲明中。 因此它確實解決了“類型中的非法文字”錯誤,但即使使用DataKinds位置仍然不允許使用文字值。

第二個錯誤告訴您編譯器無法解析“0”作為構造函數名稱。 構造函數必須以大寫字母1開頭,而0顯然不是。

當我說“類型只能包含所有其他類型的成員”時,我早先撒了謊。 實際上新類型不能包含現有類型的任何成員; 它們包含不是任何現有類型成員的全新值。 這是通過要求構造函數標記新類型的所有值來實現的; 可能的構造函數在data語句中聲明,並且它是必須在您寫入01的位置找到的構造函數的位置。

0已經是現有類型Int 2的成員,因此無論您如何聲明它,它都不能成為新類型Binary的成員。

你可以得到一個0 ,它包含在 Binary類型的Binary :也許是ConstructorName 0 但是你必須將Binary類型聲明為data Binary = ConstructorName Int | ... data Binary = ConstructorName Int | ... ; 在類型聲明中的構造函數名稱之后應該出現類型,這些類型標識可以放置在新Binary值的“槽”中的值的類型。 沒有辦法讓“槽”只能包含01 ,它必須是整個類型。


1或者是作為中綴運算符的構造函數的冒號,但這里沒有相關性。

2實際上,文字表達式0是重載的,因此它可以表示任何數字類型的零元素,但我所說的那個是Int

暫無
暫無

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

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