Комбинированный тип = один, другой или оба?

Мне интересно, возможно ли это в Haskell:

type DateTime = Date | Time | Date :+ Time

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


person Mark Cidade    schedule 30.03.2015    source источник
comment
Возможный дубликат: Есть ли канонический тип haskell для "One or Both"?   -  person Petr    schedule 30.03.2015
comment
Чтобы перейти к изюминке: Data.These   -  person J. Abrahamson    schedule 30.03.2015
comment
Кстати, «объединение значений Date и Time вместе» на самом деле является произведением обоих типов, а не суммой. В качестве ADT то, что вы хотите, записывается как DateTime = Date + Time + Date × Time или, в Haskell, Either (Either Date Time) (Date, Time). Однако лучше определить тип с помощью data, как это сделал AJFarmar, или использовать These.   -  person leftaroundabout    schedule 30.03.2015
comment
Я думал о Time как о воображаемом Date (Time = Date × sqrt(-1)) : P   -  person Mark Cidade    schedule 30.03.2015


Ответы (1)


Вы только что сделали это - конечно, это возможно!

Вот что я бы сделал:

data Both a b
    = First a
    | Second b
    | Both a b

Интересно, что это бифунктор:

import Data.Bifunctor

instance Bifunctor Both where
    bimap f _ (First a)  = First (f a)
    bimap _ g (Second b) = Second (g b)
    bimap f g (Both a b) = Both (f a) (g b)

Как Дж. Абрахамсон сказал, что в пакете These. ">Data.These, который включает в себя экземпляры Monad и Bifunctor, а также некоторые замечательные экземпляры классов типов, такие как Bifoldable и Bitraversable, на которые стоит взглянуть.

person AJF    schedule 30.03.2015
comment
Проблема с рекурсивным представлением даты и времени заключается в том, что потенциально оно может иметь более одного уровня рекурсии, что не имеет смысла. - person Eugene Sh.; 30.03.2015
comment
@ЕвгенийШ. Что вы подразумеваете под рекурсией? - person David Young; 30.03.2015
comment
Может ли Both a b включать Both (Both a b) (Both a b)? похоже на data Tree a b = Leaf a | Leaf b | Tree a b. - person Mark Cidade; 30.03.2015
comment
@Mark Cidade a и b могут обозначать любой тип - почему бы и нет? Но этот тип Дерева немного не в себе, попробуйте еще раз! - person AJF; 30.03.2015