gpt4 book ai didi

haskell - 从类型列表中获取常规列表

转载 作者:行者123 更新时间:2023-12-01 11:18:49 25 4
gpt4 key购买 nike

我找到了一种使用 ProxynatValNat 转换为 Integer 的方法可以在下面的代码中看到:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Main where

import Data.Proxy (Proxy)
import Data.Monoid ((<>))
import GHC.TypeLits

main :: IO ()
main = do
fromNat (undefined :: Proxy 5)

fromNat :: KnownNat n => Proxy n -> IO ()
fromNat proxy = do
let (num :: Integer) = natVal proxy -- converting a Nat to an Integer
putStrLn $ "Some num: " <> show num

但是我想不出一种直接的方法将类型列表转换为常规列表,下面的代码甚至没有类型检查:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Main where

import Data.Proxy (Proxy)
import Data.Monoid ((<>))
import GHC.TypeLits

main :: IO ()
main = do
fromNat (undefined :: Proxy 5)
fromListNat (undefined :: Proxy '[2,3,10])

fromNat :: KnownNat n => Proxy n -> IO ()
fromNat proxy = do
let (num :: Integer) = natVal proxy -- converting a Nat to an Integer
putStrLn $ "Some num: " <> show num

fromListNat :: Proxy [Nat] -> IO ()
fromListNat = undefined

如何将类型列表转换为常规列表?

最佳答案

答案是制作类似于 KnownNat 的内容,但用于 Nat 的类型级别列表。我们使用类型类在类型级列表上进行归纳。该类型类通过其父类(super class)约束检查您列出的所有元素是否满足 KnownNat,然后它将使用该事实重建术语级列表。

{-# LANGUAGE TypeOperators, KindSignatures #-}

-- Similar to `KnownNat (n :: Nat)`
class KnownNatList (ns :: [Nat]) where
natListVal :: proxy ns -> [Integer]

-- Base case
instance KnownNatList '[] where
natListVal _ = []

-- Inductive step
instance (KnownNat n, KnownNatList ns) => KnownNatList (n ': ns) where
natListVal _ = natVal (Proxy :: Proxy n) : natListVal (Proxy :: Proxy ns)

然后,fromListNat 采用与 fromNat 相同的形状:

fromListNat :: KnownNatList ns => Proxy ns -> IO ()
fromListNat proxy = do
let (listNum :: [Integer]) = natListVal proxy
putStrLn $ "Some list of num: " <> show listNum

将这些更改拼接到您的初始代码中,我得到了预期的输出:

$ ghc Main.hs
$ ./Main
Some num: 5
Some list of num: [2,3,10]

关于haskell - 从类型列表中获取常规列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46751129/

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