首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异构列表/ HList l -> [e]?

异构列表/ HList l -> [e]?
EN

Stack Overflow用户
提问于 2022-03-03 04:50:30
回答 1查看 118关注 0票数 1

谢谢我的另一个疑问如何在HList上编写异构列表?的答案,我可以开始使用HList:异构列表,主要是使用API of https://hackage.haskell.org/package/HList-0.5.2.0/docs/Data-HList-HList.html

现在,我要- 生成同质列表作为HList l -> [e]

hMapOut :: forall f e l. HMapOut f l e => f -> HList l -> [e]

我一直在尝试创建我自己的概念代码证明,但不知道如何正确地做到这一点。

代码语言:javascript
复制
import Data.HList (HList, hBuild, hEnd, hMap, hMapOut)

iA :: [Int]
iA = [1, 2, 3] :: [Int]

iB :: [[Char]]
iB = ["foo", "bar"] :: [[Char]]

iAiB :: HList '[[Int], [[Char]]]
iAiB = hEnd $ hBuild iA iB

flag :: Any -> Bool
flag = \iX ->  length iX >= 3  --- ERROR HERE

flags :: HList l -> [e]
flags = \iList ->
  iList & hMapOut flag

iBool :: [e]
iBool = flags iAiB

main :: IO ()
main = print iBool

这是最简单的例子,就我的目的而言,它需要封装到IO中,无论是哪种方式,它都有相同的错误。

代码语言:javascript
复制
• Couldn't match expected type ‘t0 a0’ with actual type ‘Any’
• In the first argument of ‘length’, namely ‘x’
  In the first argument of ‘(>=)’, namely ‘length x’
  In the expression: length x >= 3 typecheck(-Wdeferred-type-errors)

我认为Any类型是错误的,但我不知道如何键入。建议?

我也做了

代码语言:javascript
复制
flag :: forall (t :: * -> *) a. Foldable t => t a -> Bool
flag = \iX ->  length iX >= 3

这消除了此函数的错误,但现在又出现了另一个错误

代码语言:javascript
复制
flags :: HList l -> [e]
flags = \iList ->
  iList & hMapOut flag --- ERROR HERE

作为

代码语言:javascript
复制
• Ambiguous type variables ‘t0’,
                           ‘a0’ arising from a use of ‘hMapOut’
  prevents the constraint ‘(Data.HList.HList.HFoldr

所以,这似乎是根本的问题。

试过乐趣‘

代码语言:javascript
复制
import Data.HList (HList, hBuild, hEnd, hMap, hMapOut, Fun' (Fun'))

flags :: HList l -> [e]
flags = \iList ->
  iList & hMapOut (Fun' flag :: Fun' Foldable Bool)

错误:

代码语言:javascript
复制
• Could not deduce: b ~ Bool
  from the context: Data.HList.FakePrelude.FunCxt Foldable b
    bound by a type expected by the context:
               forall b.
               Data.HList.FakePrelude.FunCxt Foldable b =>
               Data.HList.FakePrelude.FunApp Bool b -> b
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-03 09:54:11

你的第二个版本,flag :: ∀ t a. Foldable t => t a -> Bool,是明智的。但是在HList上映射这一点有点棘手,因为约束没有表单Type -> Constraint,而是带有(Type -> Type) -> Constraintt应用程序。

由于您似乎不需要支持通用的可折叠容器( FWIW,Foldable-based定义的length is 不管怎样,有点可疑),所以我建议使用班级

代码语言:javascript
复制
flag :: ∀ l. IsList l => l -> Bool
flag = (>=3) . length . toList

或者,我们可以使用Foldable签名将Type -> Constraint快速包装到自己的类中:

代码语言:javascript
复制
class HasLength l where gLength :: l -> Int
instance Foldable t => HasLength (t a) where gLength = length

flag :: ∀ l. HasLength l => l -> Bool
flag = (>=3) . gLength

现在,这很容易折叠到一个HList上:

代码语言:javascript
复制
flags :: HMapOut (Fun IsList Bool) l Bool
           => HList l -> [Bool]
flags = hMapOut (Fun flag :: Fun IsList Bool)

注意,这是Fun,而不是Fun'。后者在这种情况下不起作用(通常也适用于HMapOut),因为函数的输入是多态的,也就是说,无法从输出类型中确定输入类型。

同样,我倾向于定义一个助手,以使这种定义更加方便:

代码语言:javascript
复制
h'MapOut :: ∀ (cxt :: Type -> Constraint) getb l
           . HMapOut (Fun cxt getb) l getb
         => (∀ a . (cxt a) => a -> getb) -> HList l -> [getb]
h'MapOut f = hMapOut (Fun f :: Fun cxt getb)

然后简单地

代码语言:javascript
复制
flags = h'MapOut @IsList flag

完整代码:

代码语言:javascript
复制
{-# LANGUAGE ScopedTypeVariables, UnicodeSyntax
        , KindSignatures, ConstraintKinds, RankNTypes
        , FlexibleContexts, FlexibleInstances
        , AllowAmbiguousTypes, TypeApplications #-}

import Data.HList
import GHC.Exts (IsList(..))
import Data.Kind

flag :: ∀ l. HasLength l => l -> Bool
flag = (>=3) . gLength
    
h'MapOut :: ∀ (cxt :: Type -> Constraint) getb l
           . HMapOut (Fun cxt getb) l getb
         => (∀ a . (cxt a) => a -> getb) -> HList l -> [getb]
h'MapOut f = hMapOut (Fun f :: Fun cxt getb)

flags :: HMapOut (Fun HasLength Bool) l Bool
           => HList l -> [Bool]
flags = h'MapOut @HasLength flag

class HasLength l where gLength :: l -> Int
instance Foldable t => HasLength (t a) where gLength = length
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71332269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档