2015-02-23 33 views
6

Mô-đun GHC.TypeLits hiện cung cấp natValsymbolVal, cho phép chúng tôi nhận giá trị thời gian chạy từ loại Nat hoặc Symbol. Có cách nào để có được giá trị thời gian chạy loại [String] trong số loại '[Symbol] không? Tôi không thể nhìn thấy một cách rõ ràng để làm điều này. Tôi có thể nghĩ về một trong đó sử dụng một typeclass với OverlappingInstances, nhưng có vẻ như GHC nên đã có một chức năng cho việc này.Chuyển đổi loại danh sách cấp thành giá trị

+0

Bạn có muốn một cái gì đó như 'forall (xs :: [Symbol]) -> HList xs -> [Chuỗi]' hoặc 'forall (xs :: [Biểu tượng]) -> Proxy xs -> [String] '. Trước đây là đơn giản, sau này là hơi ít đơn giản (bạn sẽ cần một ràng buộc loại lớp trên xs). – user2407038

+0

Tôi đang tìm cái sau. Mặc dù tôi rất tò mò muốn xem cách thức trước đây được thực hiện như thế nào (nhưng có vẻ như với tôi loại đó 'HList (xs ::' [Symbol]) 'giống như một danh sách các danh sách). Ngoài ra, tôi chưa bao giờ thấy 'forall' được sử dụng khá như thế. Không phải là một khoảng thời gian sau khi nó định lượng? –

Trả lời

7

symbolVal có thể được ánh xạ lên danh sách cấp loại. Để làm như vậy, chúng tôi cần ScopedTypeVariablesPolyKinds ngoài DataKindsTypeOperators.

{-# LANGUAGE DataKinds #-} 
{-# LANGUAGE TypeOperators #-} 
{-# LANGUAGE ScopedTypeVariables #-} 
{-# LANGUAGE PolyKinds #-} 

import Data.Proxy 
import GHC.TypeLits 

Chúng tôi sẽ định nghĩa lớp của các loại (dưới mọi hình thức) mà chúng ta có thể "được một giá trị thời gian chạy của loại [String]".

class SymbolVals a where 
    symbolVals :: proxy a -> [String] 

Chúng tôi có thể nhận danh sách các chuỗi cho bất kỳ danh sách loại trống nào.

instance SymbolVals '[] where 
    symbolVals _ = [] 

Chúng tôi có thể có danh sách các loại nơi chúng tôi có thể nhận chuỗi cho loại đầu tiên và danh sách chuỗi cho phần còn lại.

instance (KnownSymbol h, SymbolVals t) => SymbolVals (h ': t) where 
    symbolVals _ = symbolVal (Proxy :: Proxy h) : symbolVals (Proxy :: Proxy t) 
+0

Ah, rất tốt. Tôi quên rằng đây sẽ không phải là một kịch bản yêu cầu 'OverlappingInstances' vì các loại' '[] 'và' (h': t) 'không trùng lặp. Cảm ơn. –

2

Tôi khuyên bạn nên sử dụng thư viện singletons. Bạn có tất cả những gì bạn cần nhưng sử dụng Sing thay vì Proxy loại:

$ stack ghci --package singletons 
Configuring GHCi with the following packages: 
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help 
Prelude> :set -XDataKinds 
Prelude> import Data.Singletons.Prelude 
Prelude Data.Singletons.Prelude> fromSing (sing :: Sing '["a","b"]) 
["a","b"] 
Prelude Data.Singletons.Prelude> :t fromSing (sing :: Sing '["a","b"]) 
fromSing (sing :: Sing '["a","b"]) :: [String] 
Các vấn đề liên quan