[英]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 ! 当然,这仅在您首次写出类型签名时才有效…… 无论如何 ,这始终应该是您要做的第一件事 !
SList
!
† 您的类型确实应该叫树状,而不是SList
!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.