List 将列表转换为嵌套元组Haskell

List 将列表转换为嵌套元组Haskell,list,haskell,types,tuples,List,Haskell,Types,Tuples,简而言之,我的问题是,我正在解析一个数字列表([Integer]),我想将该列表转换为嵌套元组,例如,列表[1,2,3,4]将是(1,(2,(3,4)),在我看来,这似乎可以通过折叠操作实现。我认为我遇到的问题是,类型不是事先确定的,这使得元组嵌套可能是无限的 根据评论进行编辑 感谢您的良好回复,根本问题在于作业,这就是为什么更大问题的细节不多,但为了不让您怀疑我可以扩展一点,尽管我不想寻找扩展的答案。我的问题归结为上下文无关语法的右递归和右关联部分的问题,其中我有 A->n A 所以我可以得到

简而言之,我的问题是,我正在解析一个数字列表([Integer]),我想将该列表转换为嵌套元组,例如,列表[1,2,3,4]将是(1,(2,(3,4)),在我看来,这似乎可以通过折叠操作实现。我认为我遇到的问题是,类型不是事先确定的,这使得元组嵌套可能是无限的

根据评论进行编辑

感谢您的良好回复,根本问题在于作业,这就是为什么更大问题的细节不多,但为了不让您怀疑我可以扩展一点,尽管我不想寻找扩展的答案。我的问题归结为上下文无关语法的右递归和右关联部分的问题,其中我有

A->n A


所以我可以得到一个像so'na'这样的表达式,它解析为'n(n(na))'(A有其他的终端)。我可以将它解析为“[n,n,n,n]A”,这就是我想要转换的原因(我知道有更好的方法,我只是在努力寻找)。

正如Thomas M.DuBuisson评论的那样,这不是一个好方法,因为列表长度只有在运行时才知道,但不同深度的元组有不同的类型,和类型必须在编译时已知

(从技术上讲,Haskell实际上能够通过使用类型充当一种完整的动态类型语言,但这确实是不切实际的。)

然而,还有另一种方法可以实现从ish列表到元组的转换:如果您在编译时确实知道正确的深度,那么长度不匹配的列表应该是无效的输入。在这种情况下,您可以使用

{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}

class NestedTup e t where
  toNestedTup :: [e] -> Maybe t

instance NestedTup e e where
  toNestedTup [e] = Just e
  toNestedTup _ = Nothing
instance NestedTup h t => NestedTup h (h,t) where
  toNestedTup (h:t) = (h,)<$>toNestedTup t
  toNestedTup [] = Nothing

你不能这样做,因为类型依赖于数据(完全依赖于依赖类型)。谢谢你的回答,这是我得到的一种认识,但我希望我监督了一些事情。你可以定义自己的自定义类型
data t=Empty | Nonempty(Integer,t)
来表示元组的任意嵌套,但是这样做只是给标准列表类型起了另一个名字,所以没有什么好处。为什么您认为数据需要元组?另一种可能的编码:
data NTup t=Here t | There(NTup(Integer,t))
。然后可以对任何大小的嵌套元组使用
NTup()
。当您递归到
此处
时,
t
将是一个大小合适的嵌套元组(尝试
显示
查看)。这被称为非常规类型,我看不出在这个实例中这样做有什么意义,但这是一个很好的技巧。您是如何在实例定义中添加类型约束的,它是如何工作的?ghci还抱怨说打开了
TupleSections
@Yogendra,你可以这样做<代码>实例=>ClassName参数。它的工作原理是,首先选择实例,就好像没有约束一样,承诺进行该选择,然后尝试解决约束。(将其视为一个“如果-那么”,在诱惑的同时,诱使你认为你可以做你做不到的事情)
*Main> toNestedTup [1,2,3,4 :: Int] :: Maybe (Int,(Int,(Int,Int)))
Just (1,(2,(3,4)))
*Main> toNestedTup [1,2,3,4,5 :: Int] :: Maybe (Int,(Int,(Int,Int)))
Nothing