簡體   English   中英

haskell中不同元組的列表

[英]Lists of different tuples in haskell

姬,那里!

我想制作一個包含元組的列表,這樣的元組由一個字符串和第二個元素組成 integer 或 boolean

我找到了這個答案: 不同類型的元組

但我認為它有點不同,因為我必須使用我已經定義的數據,而不是使用 Int 或 Bool,問題是我不能將 Num(通過 Int)或 B(通過 Bool)放回去。

我的代碼

data EAB = Var String
        |  Num Int
        |  B Bool   
        |  Sum EAB EAB
        |  Prod EAB EAB
        |  Neg EAB
        |  Pred EAB
        |  Suc EAB
        |  And EAB EAB
        |  Or EAB EAB
        |  Not EAB
        |  Iszero EAB
        |  If EAB EAB EAB
        |  Let EAB EAB
        |  Abs String EAB 
-- Arithmetic and Boolean expression language

-- Example that I want
-- Ctx = [("x",Num),("y", B),("z", B),("w",Num)] 

-- I tried 
-- data Type = Num EAB | B EAB
-- type Ctx = [(String, Type)]
-- but doesn't work

這是因為我想定義一個 function 來告訴我是否可以根據我的 EAB 對相同類型進行評估,例如

vt :: Ctx → EAB → Type → Bool
--- ...

-- Results
vt [] 4+5 Num = True
vt [] 4+False Num = False
vt [(x,Num)] 4+x Num = True

謝謝!

只需使用新的構造函數創建一個新的類型。

data Type = NumT | BT

ctx = [("x", NumT), ("y", BT), ("z", BT), ("w", NumT)]

vt :: Ctx -> EAB -> Type -> Bool
vt [] (Sum (Num 4) (Num 5)) NumT = True -- etc.

你不能列出你想要的列表,但即使你可以,你也不能列出你的vt function。

您似乎打算使用EAB類型的BNum構造函數來表示 EAB 語言中的類型。 那是不可能的。

構造函數在 Haskell 中是特殊的,因為您可以在模式匹配中使用它們。 您可以編寫一個模式,在其中將構造函數完全應用於其他模式,然后檢查它是否與模式類型的值匹配。 像這樣:

case expr :: EAB
  of Var s -> "Var: " <> s
     Num n -> "Num: " <> show n
     B b -> "B: " <> show b

在該上下文之外,構造函數沒有什么特別的; 它們只是功能1 因此,您的Num是類型為Int -> EAB的 function,而您的B是類型為Bool -> EAB的 function。 不能以任何方式比較函數。 您可以對 function 做的唯一一件事就是將其應用(應用於正確類型的參數)並查看您得到的結果。

這意味着你想象的vt是不可能的。 在第三個參數(你說的應該是你沒有定義的Type )中,你使用了Num 但請記住, Num只是Int -> EAB類型的 function 。 vt function 實現無法查看它接收的 function 並測試它是否為Num以幫助確定返回值應該是True還是False 它唯一可能做的就是將它應用於Int ,然后檢查EAB值。

但是您可能希望能夠在該 position 中傳遞B ,以便vt可以說明給定的EAB表達式是否可以計算為 boolean 值。 B是具有不同類型Bool -> EAB的 function。 vt的第三個參數接受任一類型 function 的唯一方法是使用類型變量對其進行泛化,使該參數成為(a -> EAB) 但是vt沒有辦法知道這個 function 可以應用到什么地方,所以它甚至不能做你可以用函數做的一件事! 2個

基本上NumB不能用作您語言中類型的抽象表示。 它們是EAB數據類型中的構造函數,可幫助您使用您的語言構建和檢查值。 這就是他們的全部目的。 因此,真的沒有必要進一步探討為什么不能在列表3 (內部元組)中混合NumB ,或者如何解決它。

Daniel Wagner 建議的只是停止嘗試為此目的濫用EAB的構造函數,而只是創建一個數據類型來表示您的語言中的類型! 無論如何,這要好得多,因為EAB有 15 個構造函數,但您的語言似乎只有兩種類型。 4個

所以你只需這樣做:

data EABType = NumT | BT
  deriving (Eq, Show)

type Ctx = [(String, EABType)]
-- e.g. [("x",NumT),("y", BT),("z", BT),("w",NumT)

vt :: Ctx -> EAB -> EABType -> Bool
vt ctx expr ty
  = case expr of
      -- making some guesses about how you want vt to behave
      Var s -> (s, ty) `elem` ctx
      B _ -> ty == BT
      Num _ -> ty == NumT
      Sum l r -> ty == NumT && vt ctx l BT && vt ctx r BT
      And l r -> ty == BT && vt ctx l BT && vt ctx r BT
      ...

1除非構造函數沒有 arguments,否則它不是 function。除非通過模式匹配( Eq實例通過模式匹配簡單實現),否則您仍然無法比較它們。 但是 nullary 構造函數本身就是一個完整的模式,因此不存在您無法比較的未應用的 nullary 構造函數這樣的東西。


2假設我們可以對變量使用類型 class 約束,這可能使調用 function 成為可能。例如,如果它是(Monoid a => a -> EAB) ,那么我們總是可以用mempty調用它。 不過,您無法對這個想法做任何實際幫助您將此參數用於預期目的的事情,所以我不會 go 在這個方向上進一步。


3但要強調重點:原因與之前相同。 BNum在您使用它們的上下文中只是具有不同類型的函數,您不能在列表中混合不同類型的函數,即使可以,一旦它們在列表中,您也無法對它們執行任何操作(比如查看列表中的每個元組並檢查其中有哪個 function)。


4假設您要使用簡單的值類型,而不是嘗試將Bool -> Bool -> Bool類的類型分配給未應用的函數。

暫無
暫無

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

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