gpt4 book ai didi

haskell - 在 haskell 中使用泛型列出构造函数名称

转载 作者:行者123 更新时间:2023-12-04 01:53:31 26 4
gpt4 key购买 nike

我知道如何以下列方式列出构造函数名称:

{-# LANGUAGE DeriveGeneric        #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}

module Generics where

import Data.Proxy
import GHC.Generics

class Names' f where
names' :: Proxy f -> [String]
instance (Names' f) => Names' (M1 D t f) where
names' _ = names' (Proxy :: Proxy f)
instance (Names' f, Names' g) => Names' (f :+: g) where
names' _ = (names' (Proxy :: Proxy f) ++ (names' (Proxy :: Proxy g)))
instance (Constructor c) => Names' (C1 c f) where
names' _ = [conName (undefined :: C1 c f g)]

data Test = Foo | Bar Int | Baz { x :: Int } deriving (Generic)

main :: IO ()
main = do
print $ names' (Proxy :: Proxy (Rep Test))
--> ["Foo", "Bar", "Baz"]

但在那种情况下,我们需要一个 Proxy (Rep Test) .如何用给定的 Proxy Test 做同样的事情?

我找到了一个 example如何获得记录的第一个选择器,但不知道如何解决我的问题。请帮忙。

最佳答案

简单:

{-# LANGUAGE ScopedTypeVariables, FlexibleContexts #-}
names :: forall t. (Generic t, Names' (Rep t)) => Proxy t -> [String]
names _ = names' (Proxy :: Proxy (Rep t))

之所以有效是因为 Proxy s 无关紧要:只要您可以命名类型,您就可以构建 Proxy为了它。 (旁注:除非您使用 GHC <8,否则您应该使用 AllowAmbiguousTypesTypeApplications 扩展 Proxy 。在 GHC >=8 上,您唯一需要 Proxy 之类的东西就在更高级别的上下文。)

你也可以说
{-# LANGUAGE ScopedTypeVariables, FlexibleContexts, UndecidableInstances #-}
class (Generic t, Names' (Rep t)) => Names t where
names :: Proxy t -> [String]
instance (Generic t, Names' (Rep t)) => Names t where
names _ = names' (Proxy :: Proxy (Rep t))

获得一个很好的约束同义词 Names t(Generic t, Names' (Rep t)) .

关于haskell - 在 haskell 中使用泛型列出构造函数名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51848587/

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