Как ввести бросок

C#:

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

Haskell? Хитрый бит кажется мне, что у Haskell нет корневого текстового объекта.

Отредактированный: Я не забочусь о преобразовании в строку. Я хочу знать, как преобразовать тип (например, чтобы видеть, является ли объект Клиентом или Порядком.

14
задан Micha Wiedenmann 4 January 2019 в 12:27
поделиться

7 ответов

В Haskell все типы которые позволяют преобразование в строку, создают экземпляр класса типов Show , который предоставляет

show :: Show a => a -> String

Таким образом, весь ваш код - это не что иное, как

f x = show x

или

f = show

с тем же универсальным типом f :: Show a = > a -> String (Для всех типов a , которые могут преобразовываться в строку, принимают значение этого типа и возвращают строку).

Обратите внимание, что вам не нужно выполнять явная проверка типа во время выполнения, как в C #; общий шаблон разрешается во время компиляции. Вам не нужен полиморфный корневой тип - приведение типов, как в C #, на самом деле было бы несколько сложным и противоречило бы концепции языка. Вместо того чтобы разрешать произвольное приведение типов между типами, он определил классы типов для определенных значимых преобразований.

Обратите внимание, что совместимость проверяется во время компиляции:

-- Working
f 1
f "Hallo"
f (1, 2)
f [1, 2, 3]

-- Not working
f (\x -> x + 1) 

В ответ на ваш отредактированный вопрос :

Как я уже сказал ранее, произвольные преобразования не разрешены в Haskell (без очень небезопасного кода). А поскольку Haskell не является объектно-ориентированным, нет отношений наследования, требующих приведения типов. Просто не существует бессмысленных значений объекта , которые требовали проверки / преобразования во время выполнения. Для выражения альтернатив вам нужно будет определить тип объединения, класс типов или использовать тип Either .

В каком случае вы встретите объект, который является Customer или Заказ ? Значение такого типа просто бессмысленно. Пожалуйста, уточните еще раз. Вам понадобится класс типа:

class Loggable a where
    writeToLog :: a -> IO ()
37
ответ дан 1 December 2019 в 05:49
поделиться

If you want to have objects that can either be Customers or Orders, then you'd introduce a new datatype "Customer|Order" so that each object carries a type tag saying which it is.

I don't know the Haskell syntax offhand, but in F# it would be

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

More generally, in Haskell if you want to do something like a fixed OO type hierarchy (for a fixed set of highly related types, to be able to treat them as the same type in some cases), you may use a union type as above. On the other hand, for common operations across a variety of unrelated types (like ToString/Show) you might use a Haskell type class.

3
ответ дан 1 December 2019 в 05:49
поделиться

This is something I've tried before, and I don't think you can do it.

Introduction to Haskell Pure Functions

Haskell takes a very different approach. It starts by performing type analysis with a type checker to understand your program at compile time. The type checker strictly prohibits type casting and does not allow type errors to be ignored. Because types are checked at compile time, and there is no escape from the type checker, Haskell is frequently described as both statically typed and strongly typed.

3
ответ дан 1 December 2019 в 05:49
поделиться

Приведение и is / instanceof имеют смысл в языках, в которых есть подтипы . На ваш вопрос можно ответить несколькими способами:

  • Haskell не имеет подтипов, поэтому is / instanceof не имеет смысла в Haskell; есть только явные преобразования. Не существует типа объекта , от которого происходят все типы.
  • Классы типов в Haskell предлагают специальный полиморфизм и помогают перегрузить одно имя для множества преобразований. Например (как указывали другие) show - это перегруженное имя для преобразования любого типа в String. Классы типов также могут использоваться для того, чтобы некоторые преобразования (казались) неявными.
  • Используя классы типов, авторы общей библиотеки Scrap Your Boilerplate создали функцию безопасного преобразования ( также указали другие).
9
ответ дан 1 December 2019 в 05:49
поделиться

Дарио прав, обычно в Haskell вы хотите создать класс типа для отправки по типу чего-то. При этом есть безопасный способ преобразования типов в Haskell. Это часть общей библиотеки программирования Scrap your template , которая позволяет вам писать "интересные" части манипуляций со сложными вложенными типами данных, в то время как 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
20
ответ дан 1 December 2019 в 05:49
поделиться

Самый простой способ - использовать Data.Typeable , как отмечает Дарио, который охватывает все стандартные типы, хотя вам необходимо передать " Deriving Typeable "или иным образом реализовать typeOf , чтобы охватить ваши собственные определения типов. Это не стандартный Haskell 98, но он находится в ghc начиная с 6.2.2.

Ваш код может быть реализован:

 stringtyperep :: TypeRep
 stringtyperep = typeOf "somestring"

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

В общем, отражение типов в стиле объектно-ориентированных приложений лучше выполнять с помощью универсального программирования, но это не будет хороший пример для этого.

Кроме того, все типы в классе типов Typeable могут быть «преобразованы» в Data.Dynamic .

4
ответ дан 1 December 2019 в 05:49
поделиться

В C #, вероятно, более эффективно не выполнять приведение:

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

В Haskell есть класс типа "show", все, что реализует класс типа, может вызывать вызов show, поэтому нет требуется кастинг.

2
ответ дан 1 December 2019 в 05:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: