如何解决在purescript中组合不同类型的变体列表
我一直在玩Purescript,以此作为尝试使用类似Haskell的具有行和列多态性的语言进行编程的方法。
特别是,我使用Purescript的变体包,尝试编写一个操作,以按顺序组合两个列表的“笔记”,其中两个列表可能具有不连续的变体集。这里的想法是让用户能够将在音符的某些子集上声明的乐谱进行组合,从而自动与包含超集的乐谱进行组合,而无需执行任何显式转换。
例如,给出以下样板以简化使用变体的方式:
import Data.Variant
import Prim.Row
data A = A
data B = B
data C = C
data D = D
data E = E
data F = F
data G = G
data H = H
_A = SProxy :: SProxy "_A"
_B = SProxy :: SProxy "_B"
_C = SProxy :: SProxy "_C"
_D = SProxy :: SProxy "_D"
_E = SProxy :: SProxy "_E"
_F = SProxy :: SProxy "_F"
_G = SProxy :: SProxy "_G"
我可以定义以下类型:
type CNatural = Variant (
_A :: A,_B :: B,_C :: C,_D :: D,_E :: E,_F :: F,_G :: G)
type CPentatonic = Variant (
_A :: A,_G :: G)
鉴于这些,我可以定义两个分数:
score1 :: Array CPentatonic
score1 = [inj _A A,inj _C C]
score2 :: Array CNatural
score2 = [inj _C C,inj _B B]
因此,要结合它们,我需要签名功能
combine :: forall v w u. Union w v u =>
Array (Variant v)
-> Array (Variant w)
-> Array (Variant u)
但是,我对此的尝试:
combine x y = (map expand x) <> (map expand y)
收益
No type class instance was found for
Prim.Row.Union v2
t3
u4
The instance head contains unknown type variables. Consider adding a type annotation.
如果我尝试将Union v w u
约束更改为Union w v u
约束,则错误在第一个map expand
和第二个map expand
之间来回移动,但是我什么也没有即使我同时拥有一个Union v w u
和一个Union w v u
约束,我似乎确实可以解决这两个约束。
有什么我想念的吗?可以使用变体库在Purescript中做类似的事情吗?
解决方法
如果您想使用Variant u
来生产expand
,则必须同时要求v
和w
都是u
的子行:
module Main where
import Prelude
import Data.Variant (expand,Variant)
import Prim.Row (class Union)
combine :: forall v v_ w w_ u. Union w w_ u => Union v v_ u =>
Array (Variant v)
-> Array (Variant w)
-> Array (Variant u)
combine arr1 arr2 = map expand arr1 <> map expand arr2
Here is a working gist已加载到try.purescript中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。