Mengapa konstruktor data dengan nama yang sama tidak diizinkan dalam konstruktor tipe yang berbeda?


11

Deklarasi berikut memberikan kesalahan:

type Vec2d = (Float, Float)
type Vec3d = (Float, Float, Float)
-- Rect x y defines a rectangle spanning from (0,0) to (x,y)
data Obj2d = Rect Float Float
           | Translate Vec2d Obj2d
-- Cuboid x y z defines a cuboid spanning from (0,0,0) to (x,y,z)
data Obj3d = Cuboid Float Float Float
           | Translate Vec3d Obj3d

yaitu Multiple declarations of 'Translate'.

Sekarang, saya bertanya-tanya mengapa batasan ini diperkenalkan?

Jika batasan itu tidak ada, orang bisa menulis

Translate (1, 1) Rect 2 2 dan Translate (1, 2, 3) Cuboid 1 1 1, yang terdengar alami.

Saya tidak (segera) melihat bagaimana hal ini dapat mengakibatkan masalah penguraian penawaran untuk melarang menggunakan nama yang sama, jenisnya dapat disimpulkan oleh argumen ( Rect 2 2adalah Obj2d,, Cuboid 1 1 1adalah Obj3d)).

Saya yakin ada alasan bagus mengapa perancang bahasa memilih untuk melarang menggunakan nama yang sama untuk konstruktor data dari berbagai jenis, tetapi saya ingin belajar: mengapa, ketika itu jelas tidak diperlukan?

(Dan jenis disambiguasi adalah bisnis roti dan mentega dari Haskell!)


3
Mengenai jenis yang disimpulkan oleh argumen: Apakah Anda sadar bahwa kadang-kadang jenis argumen disimpulkan dari jenis fungsi ?

@nannan aku tidak menyadari itu ... terdengar seperti jawaban untukku. Saya selalu mengira kesimpulannya adalah dari bawah ke atas, meskipun saya bisa melihat resolusi ambiguitas menggunakan informasi jenis dari sisi lain dari grafik jenis seperti yang Anda gambarkan sebagai faktor penentu ... citra mental saya untuk ini adalah tipe pengembalian di bagian bawah grafik dan fungsi panggilan di atas, resolusi merupakan agregat dibentuk dengan melipat dari bawah, tapi itu tidak cukup seluruh gambar, adalah apa yang Anda katakan? Tidak mengherankan, dalam bahasa yang diketik tergantung dengan kesimpulan sempurna ini mungkin lebih akurat ..
Jimmy Hoffa

Jawaban:


13

Itu karena konstruktor data hanya fungsi, dan fungsi kelebihan tidak diizinkan di Haskell. Mungkin lebih jelas jika Anda menggunakan sintaks GADT untuk menentukan tipe Anda:

{-# LANGUAGE GADTs #-}
data Obj2d where
    Rect :: Float -> Float -> Obj2d   -- a function from floats to obj2d's
    Translate :: Vec2d -> Obj2d       -- a function from vec2d's to Obj2d's

Saya percaya mereka (para GHC devs) sedang mengerjakan solusi yang mungkin untuk masalah ini termasuk memperkenalkan yang baru type classuntuk semua jenis yang berbagi konstruktor data yang sama, atau yang serupa. Jadi tunggu saja, solusi untuk masalah Anda mungkin akan segera hadir! (Saya harap)


Saya pasti menantikan type classkonstruksi ini yang Anda tentukan. - Alasannya adalah: Saya tidak punya masalah, saya bisa lakukan Translate2dan Translate3d, tapi saya lebih suka tidak mencemari namespace.
A Sz

Saya bukan pengembang GHC, jadi hanya dengar-katakan saja. Saya harap itu terjadi juga.
bstamour
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.