haskell - Haskell的两级类型层次结构

标签 haskell types functional-programming

我想在我的应用程序中对4种方向建模:右,左,上和下。但是,我希望能够有一个仅对变量使用水平函数而对其他变量使用垂直函数的函数。

为了解决这个问题,我可以使用两种类型:Horizo​​ntalDirection和VerticalDirection:

data HorizontalDirection = RightDir | LeftDir
data VerticalDirection = UpDir | DownDir

foo :: HorizontalDirection -> VerticalDirection -> String
foo hDir vDir = "This works" 

但是,我也希望能够有一个可以同时使用一种类型和另一种类型的函数,如下所示:
bar :: Direction -> String
bar (HorizontalDirection _) = "Horizontal!"
bar (VerticalDirection _)   = "Vertical!"

但这是行不通的,因为Horizo​​ntalDirection和VerticalDirection都不是数据构造函数。

我知道我可以使用Either并使其正常工作,如下所示:
bar :: (Either HorizontalDirection VerticalDirection) -> String
bar (Left _) = "Horizontal!"
bar (Right _) = "Vertical!"

但是,我想知道是否可以在没有Either类型的情况下执行此操作。

我也尝试使用类型类:
data HorizontalDirection = RightDir | LeftDir
data VerticalDirection = UpDir | DownDir

class Direction a

instance Direction HorizontalDirection
instance Direction VerticalDirection

baz :: Direction d => d -> String
baz RightDir = "Horizontal"

但这给了我下面的编译器错误:
Direction.hs:21:5: error:
    • Couldn't match expected type ‘d’
                  with actual type ‘HorizontalDirection’
      ‘d’ is a rigid type variable bound by
        the type signature for:
          baz :: forall d. Direction d => d -> String
        at Direction.hs:20:1-33
    • In the pattern: RightDir
      In an equation for ‘baz’: baz RightDir = "Horizontal"
    • Relevant bindings include
        baz :: d -> String (bound at Direction.hs:21:1)

我的思维方式在这里完全错误吗?还是我只是想念一些东西?

最佳答案

您可以使用更有意义的名称声明新的数据类型,而不是使用Either

data Direction
  = Horizontal HorizontalDirection
  | Vertical   VerticalDirection

bar :: Direction -> String
bar (Horizontal _) = "Horizontal!"
bar (Vertical _) = "Vertical!"

关于haskell - Haskell的两级类型层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59162943/

相关文章:

haskell - 在 Haskell 中,两个函数看起来相等但不同

haskell - 终端作为 xmonad 中的透明壁纸

data-structures - Haskell 中的复杂数据结构——它们是如何工作的?

java - java中number/10和number*0.1的区别

python - 如何在 PEP484 之后的方法参数中设置与类相同的类型?

algorithm - 不同编程范式的算法复杂度

list - 整数的Ocaml列表到整数列表的列表(与展平相反)

haskell - 如何在Haskell中解决 "stack space overflow"

c - 有没有办法为 C 中的类型分配一个唯一编号?

lambda - 列表的最小索引 i,使得从 0 到 i 的数组元素的前缀和小于 F# 中的某个常量 c