代码之家  ›  专栏  ›  技术社区  ›  usr

如何打字

  •  14
  • usr  · 技术社区  · 16 年前

    static int F(object x)
    {
     return x is string ? 1 : 2;
    }
    

    哈斯克尔? 在我看来,棘手的一点是Haskell没有根类型 对象 .

    编辑:我不关心转换为字符串。我想知道如何打字(例如,看看 是一个 顾客 命令 .

    8 回复  |  直到 7 年前
        1
  •  37
  •   Dario    16 年前

    在Haskell中,所有允许转换为字符串的类型都实例化 Show 提供

    show :: Show a => a -> String
    

    f x = show x
    

    f = show
    

    具有相同的泛型类型 f :: Show a => a -> String (对于所有类型 a 可转换为字符串的,获取此类型的值并返回字符串)。

    注意,您不必像在C#中那样进行显式的运行时类型检查;通用模板在编译时解析。你不需要多态的根类型——像C#中的类型转换实际上有点复杂,而且违背了语言的概念。它不允许在类型之间进行任意转换,而是为某些有意义的转换定义了TypeClass。

    -- Working
    f 1
    f "Hallo"
    f (1, 2)
    f [1, 2, 3]
    
    -- Not working
    f (\x -> x + 1) 
    

    回答您编辑的问题

    正如我之前所说,Haskell中不允许任意转换(没有非常不安全的代码)。由于Haskell不是面向对象的,所以不存在需要任何强制转换的继承关系。根本没有什么意义 object 需要运行时检查/转换的值。为了表达备选方案,您必须定义联合类型、类型类或使用 Either 类型。

    在什么情况下,您遇到的对象是 Customer Order

    您需要一个typeclass:

    class Loggable a where
        writeToLog :: a -> IO ()
    
        2
  •  20
  •   Janus Troelsen    9 年前

    Dario是对的,通常在Haskell中,您希望创建一个类型类来分派某个对象的类型。话虽如此,但事实并非如此 Scrap your boilerplate 通用编程库,允许您编写复杂嵌套数据类型操作的“有趣”部分,而SYB则填补空白。大脑融合得太棒了。这里有一个关于它的演示 ppt html .

    以下是演员阵容:

    cast :: (Typeable a, Typeable b) => a -> Maybe b
    ghci> (cast 'a') :: Maybe Char
    Just 'a'
    ghci> (cast 'a') :: Maybe Bool
    Nothing
    ghci> (cast True) :: Maybe Bool
    Just True
    
        3
  •  9
  •   Martijn    16 年前

    铸造和 is / instanceof subtyping . 您的问题可以通过以下几种方式得到回答:

    • Haskell没有子类型,因此 / 运算符 object 所有类型都从中扩展的类型。
    • Haskell的类型类提供了特殊的多态性,并有助于为许多转换重载单个名称。例如(正如其他人所指出的) show 用于将任何类型转换为字符串的重载名称。类型类也可用于使某些转换(似乎)隐式。
    • 使用类型类,泛型 Scrap Your Boilerplate 图书馆创建了一个 功能(也由其他人指出)。
        4
  •  4
  •   Charles Stewart    16 年前

    Data.Typeable ,正如Dario观察到的,它涵盖了所有标准类型,尽管您需要通过“ Deriving Typeable “,或以其他方式实施 typeOf 对于要涵盖的您自己的类型定义。这不是标准的Haskell 98,但从6.2.2开始,它就在ghc中。

     stringtyperep :: TypeRep
     stringtyperep = typeOf "somestring"
    
     F :: (Typeable 'a) =>'a -> Integer
     F x | (typeOf x == stringtyperep) = 1
     F x = 2
    

    一般来说,使用泛型编程可以更好地实现OO风格的类型反射,但这不是一个很好的例子。

    此外,typeclass中的所有类型 Typeable 可以“投”进 Data.Dynamic

        5
  •  3
  •   Brian    16 年前

    如果希望对象既可以是客户,也可以是订单,那么需要引入一个新的数据类型“Customer | Order”,以便每个对象都带有一个类型标记,指明它是哪一个。

    我不知道Haskell的语法,但在F#中应该是

    type CustOrOrd =
        | Cust of Customer
        | Ord of Order
    
    let F (x:CustOrOrd) : int =
        match x with
        | Cust c -> 1
        | Ord o -> 2
    
    let thing1 = Cust someCustomer
    let thing2 = Ord someOrder
    // can call F on thing1 or thing2
    

    更一般地说,在Haskell中,如果您想执行固定的OO类型层次结构之类的操作(对于一组固定的高度相关的类型,在某些情况下可以将它们视为相同的类型),可以使用上述联合类型。另一方面,对于跨各种不相关类型(如ToString/Show)的常见操作,可以使用Haskell类型类。

        6
  •  3
  •   Farley Knight    16 年前

    这是我以前试过的,我认为你做不到。

    Introduction to Haskell Pure Functions

    方法它从执行类型开始 使用类型检查器进行分析,以 时间 严格检查字体 禁止类型转换,不允许 因为类型是在编译时检查的 时间,没有逃避的余地 类型检查器,Haskell经常

        7
  •  3
  •   Beetle    13 年前

    定义 Object

    如果您的用例非常简单,那么最好自己定义对象类型,因此:

    data Type = String | Integer | List | Bool
        deriving (Eq, Show)
    
    class Object a where
        typeOf :: a -> Type
    
    instance Object String  where typeOf _ = String
    instance Object Integer where typeOf _ = Integer
    instance Object [a]     where typeOf _ = List
    instance Object Bool    where typeOf _ = Bool
    
    f :: (Object a, Num b) => a -> b
    f x = if typeOf x == String then 1 else 2
    

    很明显,你得写一封信 instance 声明可能要在使用的函数中用作对象的每个类型 typeOf 实例 实例

    data Type = String | Integer | List | Bool | Tuple
        deriving (Eq, Show)
    
    instance Object ()              where typeOf _ = Tuple
    instance Object (a)             where typeOf _ = Tuple
    instance Object (a,b)           where typeOf _ = Tuple
    instance Object (a,b,c)         where typeOf _ = Tuple
    instance Object (a,b,c,d)       where typeOf _ = Tuple
    instance Object (a,b,c,d,e)     where typeOf _ = Tuple
    instance Object (a,b,c,d,e,f)   where typeOf _ = Tuple
    instance Object (a,b,c,d,e,f,g) where typeOf _ = Tuple
    

    使用 Data.Typeable

    如果你的用法变得更复杂,你可以试试 Data.Typeable :

    import Data.Typeable
    
    f :: (Typeable a, Num b) => a -> b
    f x = if typeOf x == typeOf (undefined::String) then 1 else 2
    

    您可以替换 (undefined::String) ""

        8
  •  2
  •   Tom    16 年前

    在C#中,不做演员可能更有效:

    return x == null ? null : x.ToString();
    

    在Haskell中有“show”类型类,任何实现该类型类的东西都可以对其调用show,因此不需要强制转换。