Por que estes não são equivalentes?
show $ if someCondition then someInt else some double
e
if someCondition then show someInt else show someDouble
Entendo que se você isolar a if ... else
parte no primeiro exemplo de uma expressão por si só, não poderá representar seu tipo com um tipo de soma anônima Int | Double
, como algo que você poderia fazer facilmente no TypeScript (mencionando o TypeScript porque é o langauge que eu costumava usar e que suporta tipos Sum), e teria que recorrer ao uso dos Either
dados que seriam chamados show
.
O exemplo que dei aqui é trivial, mas para mim faz mais sentido pensar "Ok, vamos mostrar algo, e que algo depende someCondition
", em vez de "Ok, se algumaCondição for verdadeira, mostrar someInt caso contrário mostrar someDouble" e também permitir para menos duplicação de código (aqui o programa é repetido duas vezes, mas também pode ser uma aplicação de função longa e, em vez de uma if ... else
, pode haver> 2 ramificações a serem consideradas)
Na minha opinião, deve ser fácil para o compilador verificar se cada um dos tipos que compõem o tipo de soma (aqui Int | Double
) pode ser usado como parâmetro para show
funcionar e decide se os tipos estão corretos ou não. Melhor ainda é que a show
função sempre retorna a string
qualquer que seja o tipo de parâmetro, portanto o compilador não precisa carregar todos os "desvios" possíveis (portanto, todos os tipos possíveis).
É por opção que esse recurso não existe? Ou está implementando mais difícil do que eu acho?
fonte
if ... then ... else ...
, precisa ter o mesmo tipo na partethen
eelse
. Você pode vê-lo como um operador ternário em algumas linguagens de programação.making all conversions explicit
. Na minha pergunta, não quero que Haskell faça uma conversãoInt
para aDouble
ou vice-versa. Eu apenas usei esses dois tipos como exemplo. Você pode substituir todosInt
pora
eDouble
comb
na minha pergunta, onde ambos os tipos derivamShow
. Entendo que não existeanonymous sum types
em Haskell, mas gostaria de saber por que esse é o caso e o que está nos impedindo de projetar a linguagem para tê-la.x :: Int | Bool
e precisamos compilarshow x
, não há uma maneira fácil de saber qual ponteiro usar para chamarshow
em um RTS baseado em apagamento de tipo. Provavelmente precisaríamos manter algumas informações de nível de tipo em tempo de execução.(String, Int)
não é anônimo. É apenas um tipo de produto comum com sintaxe engraçada.(String | Int)
seria muito diferente. Comece perguntando se(Int|Int)
deve ser idênticoInt
e por quê.Respostas:
Todas as partes de uma expressão devem ser bem digitadas. O tipo de
if someCondition then someInt else someDouble
teria que ser algo comoexists a. Show a => a
, mas Haskell não suporta esse tipo de quantificação existencial.Atualização: Como o chi aponta em um comentário , isso também seria possível se Haskell tivesse suporte para tipos de união / interseção (que não são iguais aos tipos de soma / produto), mas infelizmente não.
fonte
Int ∪ Double
, saberá que possui um dos dois, mas não poderá padronizar a correspondência para ver qual, portanto, você só pode fazer coisas que seriam válidas para ambas as possibilidades.typeof
operador que pode compensar a falta de marcação e ver qual tipo é usado de qualquer maneira. Haskell é totalmente apagado, por isso, se suportasse esse recurso, não haveria equivalente a isso.Existem tipos de produtos com sintaxe leve, escritos
(,)
, em Haskell. Uma coisa seria que um tipo de soma com uma sintaxe leve, algo como(Int | String)
, seria uma ótima idéia. A realidade é mais complicada. Vamos ver o porquê (estou tomando algumas liberdadesNum
, elas não são importantes).Se isso deve retornar um valor do tipo like
(Int | String)
, então o que deve retornar a seguir?(Int | Int)
obviamente, mas se isso é distinto da planície,Int
então estamos com problemas profundos. Portanto,(Int | Int)
deve ser idêntico ao simplesInt
.Pode-se ver imediatamente que essa não é apenas uma sintaxe leve para tipos de soma, mas um recurso de linguagem totalmente novo. Um tipo diferente de sistema de tipos, se você preferir. Deveríamos ter um?
Vamos olhar para esta função.
Agora que tipo
mysteryType
tem? Obviamentedireita? Agora, o que se
a
eb
são do mesmo tipo?Isso deve ficar claro
Int
como concordamos anteriormente. Agora,mysteryType
às vezes, retorna um tipo de soma anônima e, às vezes, não, dependendo dos argumentos que você passa. Como você padronizaria essa expressão? O que diabos você pode fazer com isso? Exceto coisas triviais como "show" (ou quaisquer métodos de outras classes de tipos dos quais seria uma instância), não muito. A menos que você adicione informações do tipo em tempo de execução ao idioma, isto é, ele tambémtypeof
está disponível - e isso faz do Haskell um idioma totalmente diferente.Então sim. Por que Haskell não é um TypeScript? Porque não precisamos de outro TypeScript. Se você deseja TypeScript, sabe onde encontrá-lo.
fonte