admin 管理员组文章数量: 1086019
scala2.12
l have a list of different scodec.codecs ig.
List(int(8),floatL,uint,...)
and this list is very long.
How can i get a Codec[int(8)::floatL::uint::...::HNIL]
?
I know i can do it mannualy but it cost a lot.
i tried foldLeft using codec.deriveHNil as the first param,but it turns out to be the wrong type
now i am able to add more information. i am now parsing a binary file.its hearder part contains the information of all params the data part contains, among which the most important is the frequence (each param has a different frequence and hence has different.number of values in one second/frame).following the header part is the data part,it is stored one frame after other,in every frame each param is stored one after one other(paramsA's {{frequentA}} values followed by paramB's {{frequentB}} values). there are about 300 params in the file. how can i parse this file?
the list of codecs is what i can get from the header part,but i donot know what to do next
in fact every param is a list of float values, the differences between param is that different param has different frequency(number of values per second)
scala2.12
l have a list of different scodec.codecs ig.
List(int(8),floatL,uint,...)
and this list is very long.
How can i get a Codec[int(8)::floatL::uint::...::HNIL]
?
I know i can do it mannualy but it cost a lot.
i tried foldLeft using codec.deriveHNil as the first param,but it turns out to be the wrong type
now i am able to add more information. i am now parsing a binary file.its hearder part contains the information of all params the data part contains, among which the most important is the frequence (each param has a different frequence and hence has different.number of values in one second/frame).following the header part is the data part,it is stored one frame after other,in every frame each param is stored one after one other(paramsA's {{frequentA}} values followed by paramB's {{frequentB}} values). there are about 300 params in the file. how can i parse this file?
the list of codecs is what i can get from the header part,but i donot know what to do next
in fact every param is a list of float values, the differences between param is that different param has different frequency(number of values per second)
Share Improve this question edited Mar 30 at 23:16 Dmytro Mitin 51.8k3 gold badges32 silver badges73 bronze badges asked Mar 28 at 4:29 ruoyuruoyu 32 bronze badges 3 |2 Answers
Reset to default 2There is a problem in your question that cannot be solved: you only know the type of the desired Codec
at runtime, but you try to create a Codec
for a specific type as if it were known at compiletime.
If the type of your input is List[Codec[_]]
(a list of Codec
s of unknown types), the best you can get is a Codec[? <: HList]
(a Codec
for an HList
of unknown type). That, you could do as follows:
import scodec._
import shapeless.HList
import shapeless.HNil
object ListOfCodecsToCodecHList {
def convert(list: List[Codec[_]]): Codec[? <: HList] = {
list.foldRight[Codec[? <: HList]](Codec[HNil]) { (codec, acc) =>
codec :: acc
}
}
}
That should enable you to parse your file, but the compile-time type of the parsed frames will remain unknown.
If you actually need Codec[Frame]
(Codec[int(8) :: floatL :: uint :: ... :: HNil]
doesn't make sense) you can adopt @MartinHH's solution slightly, generating Codec[List[A]]
rather than Codec[? <: HList]
:
def convert[A](list: List[Codec[A]]): Codec[List[A]] =
list.foldRight[Codec[List[A]]](Codec[HNil].xmap(_ => Nil, _ => HNil)) {
(codec: Codec[A], acc: Codec[List[A]]) =>
(codec ~ acc).xmap(
(a: A, as: List[A]) => a :: as,
{ case a :: as => (a, as) }
)
}
Then
case class ParamInfo(freq: Int)
case class Param(values: List[Float])
case class Frame(params: List[Param])
val infos = (1 to 5).map(i => ParamInfo(32 * i)).toList
val codecList: List[Codec[Param]] =
infos.map(info => fixedSizeBits(info.freq, list(float).as[Param]))
val combined: Codec[Frame] = convert(codecList).as[Frame]
combined
.encode(
Frame(
List(
Param(List(1)),
Param(List(2, 3)),
Param(List(4, 5, 6)),
Param(List(7, 8, 9, 10)),
Param(List(11, 12, 13, 14, 15))
)
)
)
.map(_.toBin)
//Successful(001111111000000000000000000000000100000000000000000000000000000001000000010000000000000000000000010000001000000000000000000000000100000010100000000000000000000001000000110000000000000000000000010000001110000000000000000000000100000100000000000000000000000001000001000100000000000000000000010000010010000000000000000000000100000100110000000000000000000001000001010000000000000000000000010000010101000000000000000000000100000101100000000000000000000001000001011100000000000000000000)
combined.decode(
bin"001111111000000000000000000000000100000000000000000000000000000001000000010000000000000000000000010000001000000000000000000000000100000010100000000000000000000001000000110000000000000000000000010000001110000000000000000000000100000100000000000000000000000001000001000100000000000000000000010000010010000000000000000000000100000100110000000000000000000001000001010000000000000000000000010000010101000000000000000000000100000101100000000000000000000001000001011100000000000000000000"
)//Successful(DecodeResult(Frame(List(Param(List(1.0)), Param(List(2.0, 3.0)), Param(List(4.0, 5.0, 6.0)), Param(List(7.0, 8.0, 9.0, 10.0)), Param(List(11.0, 12.0, 13.0, 14.0, 15.0)))),BitVector(empty)))
https://scastie.scala-lang./DmytroMitin/tpEHXF70SJ2BymyAR2Wd2w/3
本文标签:
版权声明:本文标题:scala - how can i get a Codec[int(8)::floatL::uint::…] from List(int(8),floatL,uint,…) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744057053a2526041.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
scodec
(like me) but it looks like aflatten
orfold
orreduce
operation of some kind. – Tim Commented Mar 28 at 7:04Codec
do you want to obtain (acirce.io.Codec
maybe?)? What type isint(8)::floatL::uint::...
supposed to be (ashapeless.HList
maybe?)? – MartinHH Commented Mar 28 at 7:41HList
of codecs and not a simpleList
(!), but I'm not a shapeless expert. – MartinHH Commented Mar 28 at 9:44