In Elm, non riesco a capire quando type
è la parola chiave appropriata rispetto a type alias
. La documentazione non sembra avere una spiegazione di ciò, né posso trovarne una nelle note di rilascio. Questo è documentato da qualche parte?Differenza tra Elm e tipo alias?
risposta
Come ci penso:
type
è usato per definire nuovi tipi di unione:
type Thing = Something | SomethingElse
Prima di questa definizione Something
e SomethingElse
non significava nulla. Ora sono entrambi di tipo Thing
, che abbiamo appena definito.
type alias
è usato per dare un nome a qualche altro tipo che già esiste:
type alias Location = { lat:Int, long:Int }
{ lat = 5, long = 10 }
è di tipo { lat:Int, long:Int }
, che era già un tipo valido. Ma ora possiamo anche dire che ha tipo Location
perché è un alias per lo stesso tipo.
Vale la pena notare che quanto segue si compila bene e visualizza "thing"
. Anche se specifichiamo thing
è un String
e aliasedStringIdentity
prende un AliasedString
, non otteniamo un errore che ci sia un tipo di mancata corrispondenza tra String
/AliasedString
:
import Graphics.Element exposing (show)
type alias AliasedString = String
aliasedStringIdentity: AliasedString -> AliasedString
aliasedStringIdentity s = s
thing : String
thing = "thing"
main =
show <| aliasedStringIdentity thing
La chiave è la parola alias
. Nel corso della programmazione, quando si vuole le cose che appartengono gruppo insieme, lo metti in un record, come nel caso di un punto
{ x = 5, y = 4 }
o un record di studente.
{ name = "Billy Bob", grade = 10, classof = 1998 }
Ora, se è necessario passare questi record in giro, che avrebbe dovuto precisare l'intero tipo, come:
add : { x:Int, y:Int } -> { x:Int, y:Int } -> { x:Int, y:Int }
add a b =
{ a.x + b.x, a.y + b.y }
Se si potesse alias un punto, la firma sarebbe così molto più facile da scrivere!
type alias Point = { x:Int, y:Int }
add : Point -> Point -> Point
add a b =
{ a.x + b.x, a.y + b.y }
Quindi un alias è una scorciatoia per qualcos'altro. Qui, è una scorciatoia per un tipo di record. Puoi pensare a come dare un nome a un tipo di record che utilizzerai spesso. Ecco perché si chiama alias: è un altro nome per il tipo di record nudo rappresentato da { x:Int, y:Int }
considerando che type
risolve un problema diverso. Se provieni da OOP, è il problema che risolvi con ereditarietà, sovraccarico dell'operatore, ecc .-- a volte, vuoi trattare i dati come una cosa generica, ea volte vuoi trattarli come una cosa specifica.
Un luogo comune in cui ciò accade è quando si passano messaggi come il sistema postale. Quando invii una lettera, vuoi che il sistema postale tratti tutti i messaggi come la stessa cosa, quindi devi solo progettare il sistema postale una volta. E inoltre, il compito di instradare il messaggio dovrebbe essere indipendente dal messaggio contenuto all'interno.È solo quando la lettera raggiunge la sua destinazione, ti interessa ciò che il messaggio è.
Allo stesso modo, potremmo definire uno type
come unione di tutti i diversi tipi di messaggi che potrebbero accadere. Diciamo che stiamo implementando un sistema di messaggistica tra studenti universitari e genitori. Quindi ci sono solo due messaggi che i ragazzi del college possono inviare: "Ho bisogno di soldi per la birra" e "Ho bisogno di mutande".
type MessageHome = NeedBeerMoney | NeedUnderpants
Così ora, quando progettiamo il sistema di routing, i tipi per le nostre funzioni può semplicemente passare intorno MessageHome
, invece di preoccuparsi di tutti i diversi tipi di messaggi potrebbe essere. Il sistema di routing non interessa. Basta sapere che è un MessageHome
. È solo quando il messaggio raggiunge la sua destinazione, la casa dei genitori, che è necessario capire di cosa si tratta.
case message of
NeedBeerMoney ->
sayNo()
NeedUnderpants ->
sendUnderpants(3)
Se si conosce l'architettura Elm, la funzione di aggiornamento è una dichiarazione caso gigante, perché questa è la destinazione dove il messaggio viene instradato, e quindi elaborati. E usiamo i tipi di unione per avere un singolo tipo da trattare quando si passa il messaggio in giro, ma poi possiamo usare una dichiarazione del caso per capire esattamente quale messaggio fosse, quindi possiamo gestirlo.
La differenza principale, a mio avviso, è se il tipo di controllo vi urlerà se si utilizza il tipo "synomical".
Creare il seguente file, metterlo da qualche parte ed eseguire elm-reactor
, poi vai a http://localhost:8000
per vedere la differenza:
-- Boilerplate code
module Main exposing (main)
import Html exposing (..)
main =
Html.beginnerProgram
{
model = identity,
view = view,
update = identity
}
-- Our type system
type alias IntRecordAlias = {x : Int}
type IntRecordType =
IntRecordType {x : Int}
inc : {x : Int} -> {x : Int}
inc r = {r | x = .x r + 1}
view model =
let
-- 1. This will work
r : IntRecordAlias
r = {x = 1}
-- 2. However, this won't work
-- r : IntRecordType
-- r = IntRecordType {x = 1}
in
Html.text <| toString <| inc r
Se decommentare 2.
e commentare 1.
si vedrà:
The argument to function `inc` is causing a mismatch.
34| inc r
^
Function `inc` is expecting the argument to be:
{ x : Int }
But it is:
IntRecordType
Non
- 1. Distinzione tra tipo alias e tipo lambda
- 2. differenza tra dove e avere rispetto alias
- 3. Tipo annotazioni in Elm REPL
- 4. Differenza tra tipo generico e tipo jolly
- 5. Qual è la differenza tra `alias` e` typedef`?
- 6. Qual è la differenza tra xtype e alias?
- 7. Differenza tra parametri tipo e indici?
- 8. Differenza tra tipo (obj) e obj .__ class__
- 9. C'è qualche differenza tra tipo e classe?
- 10. Elm: digita alias per JSON con la proprietà "type"
- 11. Qual è la differenza tra il metodo alias e il simbolo alias?
- 12. Qual è la differenza tra l'utilizzo di un tipo come un nome diverso e un alias di tipo?
- 13. Qual è la differenza tra (tipo) valore e tipo (valore)?
- 14. Compilatore Elm in Elm?
- 15. Elm personalizzato complesso JSON decoder
- 16. Differenza tra Type.IsGenericTypeDefinition e Type.ContainsGenericParameters
- 17. Differenza tra FileContentResult e FileStreamResult
- 18. Differenza tra std :: eccezione e "..."
- 19. Differenza tra tipo e classe in fortran 2003
- 20. In Typescript, qual è la differenza tra tipo e interfaccia?
- 21. C'è una differenza tra MIME e tipo di contenuto?
- 22. WPF stili: differenza tra x: Nome e x: Tipo
- 23. Differenza tra dichiarazioni di "tipo script" e "linguaggio di script"
- 24. Differenza tra tipo array e array allocati con malloc
- 25. Differenza tra installazione bundle e bundle
- 26. differenza tra DateTime e DateTime2
- 27. Differenza tra viewDidLoad e viewDidAppear
- 28. Differenza tra IntPtr e UIntPtr
- 29. Elm: come funziona la cassetta postale?
- 30. Differenza tra Enum.GetValues e Enum.GetNames
sicuro del tuo punto dell'ultimo paragrafo. Stai cercando di dire che sono sempre dello stesso tipo, non importa come lo si alias? –
Sì, solo sottolineando che il compilatore considera il tipo di alias essere uguale all'originale – robertjlooby
Quindi quando si utilizza la sintassi del record '{}', si sta definendo un nuovo tipo? –