简体   繁体   English

创建数据类型列表Haskell

[英]Creating a data type list Haskell

I've done a personal list in Haskell like this: (2,(1,1),3) -> List [Num 2, List [Num 1, Num 1], List [Num 3]]. 我已经在Haskell中完成了一个个人列表,如下所示:(2,(1,1),3)->列表[数字2,列表[数字1,数字1],列表[数字3]]。

This is how I made it: 这是我的方法:

data SList a = Num a | List [SList a] deriving Show
emptySList :: SList a
emptySList = (List [])

consElem :: a -> SList a -> SList a
consElem x (List y) = (List ((Num x) : y))

consList :: SList a -> SList a -> SList a
consList a b = (List [a,b])

I manage to form this list (List [Num 2, List [Num 1, Num 1], List [Num 3]]) using consElem and consList like this: 我设法使用consElem和consList来形成此列表(列表[Num 2,列表[Num 1,Num 1],列表[Num 3]]),如下所示:

consElem 2 $ consList (consElem 1 $ consElem 1 emptySList) $ consElem 3 emptySList

I wonder how can I transform a SList in a normal list. 我想知道如何在常规列表中转换SList。 For example if I have this SList: List [Num 2, List [Num 1, Num 1], List [Num 3]] it should become [2,1,1,3] . 例如,如果我有此SList: List [Num 2, List [Num 1, Num 1], List [Num 3]]它应该变为[2,1,1,3]

My attempt: 我的尝试:

atomToNormal x
    | null x = []
    | otherwise = slistToList (head x) ++ atomToNormal (tail x)
slistToList :: SList a -> [a]
slistToList (List x) = atomToNormal x
slistToList (Num x) = [x]

GHC can actually write this function for you: GHC实际上可以为您编写此功能:

{-# LANGUAGE DeriveFoldable #-}
import Data.Foldable as Foldable

data SList a = Num a | List [SList a]
  deriving (Show, Foldable)

slistToList :: SList a -> [a]
slistToList = Foldable.toList

If you want to do it yourself – I don't see quite what atomToNormal is supposed to do, you don't need it. 如果您想自己做–我不太明白atomToNormal应该做什么,那么您就不需要它。 Just deconstruct the tree-branch list head-first right in slistToList : 只需在slistToList解构树分支列表 head-first slistToList

slistToList :: SList a -> [a]
slistToList (Num x) = _
slistToList (List []) = _
slistToList (List (l:ls)) = _

Now fill in the gaps. 现在填补空白。 GHC (>=7.10) can help you a lot there too: just try compiling as-is with the underscore-gaps, and it will tell you GHC(> = 7.10)也可以为您提供很多帮助:只需尝试使用下划线空白按原样编译,它将告诉您

/tmp/wtmpf-file17703.hs:8:23:
    Found hole ‘_’ with type: [a]
    Where: ‘a’ is a rigid type variable bound by
               the type signature for slistToList :: SList a -> [a]
               at /tmp/wtmpf-file17703.hs:7:16
    Relevant bindings include
      x :: a (bound at /tmp/wtmpf-file17703.hs:8:18)
      slistToList :: SList a -> [a]
        (bound at /tmp/wtmpf-file17703.hs:8:1)
    In the expression: _
    In an equation for ‘slistToList’: slistToList (Num x) = _

So the first gap needs to have type [a] , and the only value you have is x::a . 因此,第一个间隙必须具有[a]类型,并且唯一的值是x::a Well, you can wrap that in a singleton list 好吧,您可以将其包装在单例列表中

slistToList (Num x) = [x]

Proceed in the same fashion with the other clauses. 与其他子句的处理方式相同。 As a rule of thumb, if you just somehow include all of the “relevant bindings” (often, there's exactly one way to do this), then your implementation will probably be right. 根据经验,如果仅以某种方式包括所有“相关绑定”(通常,只有一种方法可以做到这一点),那么您的实现可能是正确的。

Of course, this only works when you first write out the type signature... which should always be the first thing you do anyway ! 当然,这仅在您首次写出类型签名时才有效…… 无论如何 ,这始终应该是您要做的第一件事


Your type really should be called something tree-ish, not SList ! 您的类型确实应该叫树状,而不是SList

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM