简体   繁体   English

Haskell中两个不相关类型之间的大小写

[英]Case between two unrelated types in Haskell

Is it possible to use case expression between two unrelated types in Haskell, like in this example (not working) code: 是否可以在Haskell中的两个不相关类型之间使用case表达式,就像在这个示例(不工作)代码中一样:

data A = A
data B = B

f x = case x of
  A -> 1
  B -> 2

main = do
  print $ test A
  return ()

I know I can use Either here, but this code is not meant to be used - I want to deeply learn the Haskell type system and see what could be done. 我知道我可以在这里使用Either ,但是这段代码并不打算使用 - 我想深入学习Haskell类型系统并看看可以做些什么。

A and B are distinct types. AB是不同的类型。 If you want a function that can take values of multiple types, you need a typeclass. 如果您想要一个可以获取多种类型值的函数,则需要一个类型类。

data A = A
data B = B

class F a where
  f :: a -> Int

instance F A where
  f _ = 1

instance F B where
  f _ = 2

main = do
  print $ f A

No, this is not possible with a normal case statement, but you can hack this sort of thing using type classes: 不,这对于正常的case语句是不可能的,但是你可以使用类型类来破解这种事情:

data A = A
data B = B

class Test a where
    test :: a -> Int

instance Test A where test = const 1
instance Test B where test = const 2

main = print $ test A

But you should only use this if it's really required, as it gets messy very soon and you end up with needing a lots of extensions to the type system (UndecidableInstances, OverlappingInstances, ...) 但是你应该只使用它,如果真的需要它,因为它很快会变得混乱,你最终需要对类型系统进行大量扩展(UndecidableInstances,OverlappingInstances,...)

Rather than writing your own type class for f, you could use the Typeable class which has some support by ghc. 您可以使用具有ghc支持的Typeable类,而不是为f编写自己的类型类。 You don't need to use Dynamic here, but in some cases it is needed. 您不需要在此处使用Dynamic,但在某些情况下需要使用Dynamic。

{-# LANGUAGE DeriveDataTypeable #-}
import Data.Dynamic

data A = A deriving (Typeable)
data B = B deriving (Typeable)

f x | Just A <- fromDynamic x = 1
    | Just B <- fromDynamic x = 2

f2 x | Just A <- cast x = 1
     | Just B <- cast x = 2

main = do
  print $ f (toDyn A)
  print $ f2 A

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

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