Tunggu, bahasa apa ini?


37

Baru-baru ini saya merasa senang menulis sebuah program Haskell yang dapat mendeteksi jika NegativeLiteralsekstensi terlibat. Saya datang dengan yang berikut:

data B=B{u::Integer}
instance Num B where{fromInteger=B;negate _=B 1}
main=print$1==u(-1)

Cobalah online!

Ini akan mencetak secara Truenormal dan Falsesebaliknya.

Sekarang aku sangat senang melakukan ini. Aku memperluas tantangan untuk kalian semua. Ekstensi bahasa Haskell apa lagi yang bisa Anda crack?

Aturan

Untuk memecahkan ekstensi bahasa tertentu, Anda harus menulis program Haskell yang mengkompilasi dengan dan tanpa ekstensi bahasa (peringatan baik-baik saja) dan menghasilkan dua nilai non-kesalahan yang berbeda ketika dijalankan dengan ekstensi bahasa dan dimatikan (dengan menambahkan Noawalan ke ekstensi bahasa). Dengan cara ini kode di atas dapat disingkat menjadi hanya:

data B=B{u::Integer}
instance Num B where{fromInteger=B;negate _=B 1}
main=print$u(-1)

yang mencetak 1dan -1.

Metode apa pun yang Anda gunakan untuk memecahkan ekstensi harus spesifik untuk ekstensi itu. Mungkin ada cara mendeteksi sewenang-wenang apa bendera compiler atau LanguageExtensions diaktifkan, jika demikian metode tersebut tidak diperbolehkan. Anda dapat mengaktifkan ekstensi bahasa tambahan atau mengubah pengoptimalan kompiler menggunakan -Otanpa biaya ke jumlah byte Anda.

Ekstensi bahasa

Anda tidak dapat retak ekstensi bahasa yang tidak memiliki Norekan (misalnya Haskell98, Haskell2010, Unsafe, Trustworthy, Safe) karena ini tidak jatuh di bawah ketentuan yang diuraikan di atas. Setiap ekstensi bahasa lainnya adalah permainan yang adil.

Mencetak gol

Anda akan diberikan satu poin untuk setiap ekstensi bahasa Anda adalah orang pertama yang diretas dan satu poin tambahan untuk setiap ekstensi bahasa yang Anda miliki celahnya yang terpendek (diukur dalam byte). Untuk poin kedua, ikatan akan diputus untuk pengajuan sebelumnya. Skor yang lebih tinggi lebih baik

Anda tidak akan dapat mencetak poin untuk pengiriman pertama pada NegativeLiteralsatau QuasiQuoteskarena saya telah memecahkannya dan memasukkannya ke dalam tubuh pos. Namun Anda akan dapat mencetak poin untuk celah terpendek dari masing-masing. Inilah celah sayaQuasiQuotes

import Text.Heredoc
main=print[here|here<-""] -- |]

Cobalah online!


3
Saya pikir ini adalah daftar semua opsi yang valid
H.PWiz

1
Perhatikan bahwa komentar saya di atas tidak termasuk NondecreasingIndentationkarena alasan yang jelas
H.PWiz

4
Saya pikir judul ini menyesatkan, karena satu-satunya bahasa yang dapat Anda gunakan adalah Haskell. Bagaimana Wait, what language extension is this?Atau sesuatu yang sama sekali berbeda.
MD XF

1
Saya cukup penasaran apakah mungkin retak RelaxedPolyRec, untuk kompiler yang cukup kuno untuk benar - benar mendukung mematikannya. (Pilihan ada di sana, dengan dokumentasi, selama beberapa tahun setelah itu berhenti melakukan apa pun.)
dfeuer

1
@ PDFeuer Melihat tiket ini, sepertinya GHC 6.12.1 mendukung untuk mematikannya.
Ørjan Johansen

Jawaban:


24

MagicHash, 30 byte

x=1
y#a=2
x#a=1
main=print$x#x

-XMagicHash output 1, -XNoMagicHash output 2

MagicHash memungkinkan nama variabel berakhir di a #. Oleh karena itu dengan ekstensi, ini mendefinisikan dua fungsi y#dan x#yang masing-masing mengambil nilai dan mengembalikan konstanta 2, atau 1.x#xakan mengembalikan 1 (karena x#diterapkan ke 1)

Tanpa ekstensi, ini mendefinisikan satu fungsi #yang mengambil dua argumen dan mengembalikan 2. Itu x#a=1adalah pola yang tidak pernah tercapai. Kemudian x#xadalah 1#1, yang mengembalikan 2.


2
Saya sekarang menyanyikan X Magic Hash untuk lagu Dance Magic Dance . Semoga kamu bangga!
TRiG

Saya heran bahwa MagicHashtidak memungkinkan hash non-trailing. Aneh!
dfeuer

18

CPP, 33 20 byte

main=print$0-- \
 +1

Mencetak 0dengan -XCPPdan 1dengan -XNoCPP.

Dengan -XCPP, garis miring \sebelum baris baru menghapus baris baru, sehingga kode menjadi main=print$0-- +1dan hanya0 dicetak karena +1sekarang menjadi bagian dari komentar.

Tanpa bendera, komentar diabaikan dan baris kedua diuraikan sebagai bagian dari baris sebelumnya karena diindentasi.


Pendekatan sebelumnya dengan #define

x=1{-
#define x 0
-}
main=print x

Juga mencetak 0dengan -XCPPdan 1dengan -XNoCPP.


2
Ya Tuhan, sampai sekarang saya agak berpikir GHC akan menghapus komentar Haskell sebelum beralih ke CPP.
Kubik

@Cubic Apakah ini bukan pre -processor?
Bergi

1
@Bergi Tentu, tetapi pra- prosesor tidak selalu berarti "adalah hal pertama yang berjalan", terutama karena GHC harus melewati file terlebih dahulu untuk menemukan pragma. Saya kira komentar disimpan dalam komentar jadi dokumen dan pekerjaan sejenisnya setelah CPP selesai.
Kubik


14

BinaryLiterals, 57 byte

b1=1
instance Show(a->b)where;show _=""
main=print$(+)0b1

-XBinaryLiterals mencetak satu baris baru. -XNoBinaryLiterals mencetak a 1.

Saya yakin ada cara yang lebih baik untuk melakukan ini. Jika Anda menemukannya, silakan posting.


Tidak bisakah Anda mendefinisikan bsebagai suatu fungsi (jadi tidak ada biner menjadi b(0, 1), tetapi biner menjadi 0b1)?
NoOneIsHere

12

MonomorphismRestriction + 7 others, 107 byte

Ini menggunakan TH yang membutuhkan bendera -XTemplateHaskell setiap saat.

File T.hs, 81 + 4 byte

module T where
import Language.Haskell.TH
p=(+)
t=reify(mkName"p")>>=stringE.show

Utama, 22 byte

import T
main=print $t

Mengkompilasi dengan flag MonomorphismRestriction memaksa tipe pto Integer -> Integer -> Integerdan dengan demikian menghasilkan output sebagai berikut:

"VarI T.p (AppT (AppT ArrowT (ConT GHC.Integer.Type.Integer)) (AppT (AppT ArrowT (ConT GHC.Integer.Type.Integer)) (ConT GHC.Integer.Type.Integer))) Nothing"

Mengkompilasi dengan flag NoMonomorphismRestriction meninggalkan tipe ppaling umum, yaitu. Num a => a->a->a- Memproduksi sesuatu seperti (disingkat VarTnama menjadi a):

"VarI T.p (ForallT [KindedTV a StarT] [AppT (ConT GHC.Num.Num) (VarT a)] (AppT (AppT ArrowT (VarT a)) (AppT (AppT ArrowT (VarT a)) (VarT a)))) Nothing"

Cobalah secara online!


Alternatif

Karena kode di atas hanya mencetak tipe p, ini dapat dilakukan dengan semua flag yang entah bagaimana mempengaruhi bagaimana Haskell menyimpulkan tipe. Saya hanya akan menentukan flag dan dengan apa yang akan menggantikan fungsi pdan jika diperlukan flag tambahan (selain itu-XTemplateHaskell ):

Daftar Overloaded, 106 byte

Selain itu kebutuhan -XNoMonomorphismRestriction:

p=[]

Baik p :: [a]atau p :: IsList l => l, coba online!

OverloadedStrings, 106 byte

Selain itu kebutuhan -XNoMonomorphismRestriction:

p=""

Baik p :: Stringatau p :: IsString s => s, coba online!

PolyKinds, 112 byte

Ini sepenuhnya karena @CsongorKiss:

data P a=P 

Baik P :: P aatau P :: forall k (a :: k). P a, coba online!

Pemahaman Monad, 114 byte

p x=[i|i<-x]

Baik p :: [a] -> [a]atau p :: Monad m => m a -> m a, coba online!

NamedWildCards, 114 byte

Yang ini ditemukan oleh @Laikoni, juga membutuhkan -XPartialTypeSignatures:

p=id::_a->_a

Keduanya memiliki tipe save ( p :: a -> a) tetapi GHC menghasilkan nama yang berbeda untuk variabel, coba online!

ApplicativeDo, 120 byte

p x=do i<-x;pure i

Baik p :: Monad m => m a -> m aatau p :: Functor f => f a -> f a, coba online!

Label Overloaded, 120 byte

Ini perlu bendera tambahan -XFlexibleContexts:

p x=(#id)x
(#)=seq

Baik tipe p :: a -> b -> batau p :: IsLabel "id" (a->b) => a -> b, coba secara online!


Apakah hal serupa berfungsi untuk bendera lain?
H.PWiz

Ya, Anda bisa melakukannya dengan OverloadedStringsatau OverloadedListspasti dan mungkin juga orang lain ..
ბიმო

2
Ini juga berfungsi dengan PolyKinds: Coba online!
Csongor Kiss

1
Tampaknya juga berfungsi dengan NamedWildCards: Coba online! (Membutuhkan -XPartialTypeSignatures)
Laikoni

10

CPP, 27 25

main=print({-/*-}1{-*/-})

Cobalah online!

Cetakan ()untuk -XCPPdan 1untuk-XNoCPP

Versi sebelumnya:

main=print[1{-/*-},2{-*/-}]

Cobalah online!

Mencetak [1]dengan -XCPPdan [1,2]sebaliknya.

Penghargaan: Ini terinspirasi oleh jawaban Laikoni, tetapi alih-alih #definehanya menggunakan komentar C.


9

ScopedTypeVariables, 162 113 byte

instance Show[()]where show _=""
p::forall a.(Show a,Show[a])=>a->IO()
p a=(print::Show a=>[a]->IO())[a]
main=p()

Cetakan -XScopedTypeVariables"" (kosong), -XNoScopedTypeVariables dicetak "[()]".

Sunting: solusi yang diperbarui berkat saran yang bermanfaat di komentar


1
Ah saya mengerti. Secara umum lebih baik untuk memasukkan kode Anda ke dalam tubuh, tetapi versi yang tidak serigala juga bagus. Saya juga memperhatikan bahwa "T"hanya bisa diganti dengan "".
Wheat Wizard

2
Hal lain yang dapat Anda lakukan adalah mengganti datatype Anda Tdengan (). Untuk menghindari harus mendefinisikannya. Cobalah online!
Wheat Wizard

1
Tangkapan yang bagus, saya baru menyadari bahwa pragma yang tidak jelas dapat dimasukkan sebagai bendera: Cobalah secara online!
Csongor Kiss

2
Selain itu show dapat diubah untuk cetak
H.PWiz

Sintaks Unicode untuk forallakan menghemat beberapa byte. Saya ragu solusi apa pun yang membutuhkan contoh tambahan memiliki banyak harapan untuk menang.
dfeuer

9

MonoLocalBinds, GADTs, atau TypeFamilies, 36 32 byte

EDIT:

  • -4 byte: Versi ini dimasukkan ke dalam rantai poliglot besar oleh stasoid, yang mengejutkan saya dengan meletakkan semua deklarasi di tingkat atas. Rupanya memicu pembatasan ini tidak memerlukan binding lokal yang sebenarnya .
a=0
f b=b^a
main=print(f pi,f 0)
  • Tanpa ekstensi , program ini dicetak (1.0,1).
  • Dengan salah satu flag -XMonoLocalBinds , -XGADTs , atau -XTypeFamilies , ia mencetak (1.0,1.0).

  • The MonoLocalBindsekstensi ada untuk mencegah beberapa jenis inferensi unintuitive dipicu oleh GADTs dan keluarga jenis. Dengan demikian, ekstensi ini diaktifkan secara otomatis oleh dua lainnya.

  • Hal ini dimungkinkan untuk mematikannya lagi secara eksplisit dengan -XNoMonoLocalBinds, trik ini mengasumsikan Anda tidak.
  • Seperti sepupunya yang lebih terkenal, pembatasan monomorfisme, MonoLocalBindsbekerja dengan mencegah beberapa nilai ( dalam binding lokal seperti letatau where, dengan demikian nama itu juga dapat terjadi pada level atas) dari polimorfik. Meskipun dibuat untuk inferensi tipe yang lebih waras, aturan kapan pemicunya adalah jika mungkin bahkan lebih berbulu dari MR.

  • Tanpa ekstensi apa pun, program di atas menyimpulkan jenisnya f :: Num a => a -> a, memungkinkan f piuntuk default ke Doubledan f 0ke Integer.

  • Dengan ekstensi, jenis yang disimpulkan menjadi f :: Double -> Double, dan f 0harus mengembalikan Doublejuga.
  • Variabel yang terpisah a=0diperlukan untuk memicu aturan teknis: aterkena pembatasan monomorphism, dan amerupakan variabel bebas dari f, yang berarti bahwa f's kelompok yang mengikat tidak sepenuhnya umum , yang berarti ftidak ditutup sehingga tidak menjadi polimorfik.

9

OverloadedStrings, 65 48 32 byte

Mengambil keuntungan dari RebindableSyntax, gunakan versi kami sendiri dari Strtring untuk mengubah string literal menjadi "y".

main=print""
fromString _=['y']

Harus dikompilasi dengan -XRebindableSyntax -XImplicitPrelude.

Tanpa -XOverloadedStringscetakan ""; dengan cetakan "y".

Juga, baru saja saya sadar bahwa teknik yang sama bekerja dengan (misalnya) Daftar Beban Berlebih:

Daftar Overloaded, 27 byte

main=print[0]
fromListN=(:)

Harus dikompilasi dengan -XRebindableSyntax -XImplicitPrelude.

Tanpa -XOverloadedListscetakan [0]; dengan cetakan [1,0].


1
Anda dapat mempersingkat baris terakhir menjadi fromString a=['y'].
Ørjan Johansen

Ruang di print "n"juga bisa dijatuhkan.
Laikoni

@ ØrjanJohansen terima kasih! Saya mengalami kegagalan dengan ="y", tetapi =['y']berfungsi dengan baik!
felixphew

1
Anda dapat menghapus yang kedua ndariprint"n"
Wheat Wizard

1
Anda juga dapat menggunakan -XImplicitPreludesetelah RebindableSyntaxuntuk menghindari jalur impor.
dfeuer

8

BangPatterns, 32 byte

(!)=seq
main|let f!_=0=print$9!1

-XBangPatterns mencetak 1sedangkan -XNoBangPatterns akan mencetak 0.

Ini menggunakan bendera BangPatterns yang memungkinkan untuk membubuhi keterangan pola dengan !untuk memaksa evaluasi ke WHNF, dalam hal ini 9!1akan menggunakan definisi tingkat atas (!)=seq. Jika bendera tidak diaktifkan, f!_tentukan operator baru (!)dan bayangan definisi tingkat atas.


7

ApplicativeDo, 104 byte

import Control.Applicative
z=ZipList
instance Monad ZipList where _>>=_=z[]
main=print$do a<-z[1];pure a

Cobalah online!

Dengan ApplicativeDo, ini tercetak

ZipList {getZipList = [1]}

Tanpanya, ia mencetak

ZipList {getZipList = []}

ZipListadalah salah satu dari beberapa jenis di pustaka dasar dengan turunan untuk Applicativetetapi tidak untuk Monad. Mungkin ada alternatif yang lebih pendek mengintai di suatu tempat.


7

Ketat, 87 84 82 byte

-5 byte berkat dfeuer !

Mungkin kurang dengan BlockArgumentsmenyimpan parens di sekitar \_->print 1:

import Control.Exception
0!_=0
main=catch @ErrorCall(print$0!error"")(\_->print 1)

Menjalankan ini dengan -XStrict mencetak 1sedangkan menjalankannya dengan -XNoStrict akan mencetak a 0. Ini menggunakan bahwa Haskell secara default malas dan tidak perlu mengevaluasi error""karena sudah tahu bahwa hasilnya akan 0ketika cocok dengan argumen pertama dari(!) , perilaku ini dapat diubah dengan bendera itu - memaksa runtime untuk mengevaluasi kedua argumen.

Jika mencetak apa pun dalam satu kasus diperbolehkan, kami dapat menurunkannya hingga 75 byte menggantikan main by (juga beberapa byte dimatikan oleh dfeuer ):

main=catch @ErrorCall(print$0!error"")mempty

StrictData, 106 99 93 byte

-15 byte berkat dfeuer !

Ini pada dasarnya melakukan hal yang sama tetapi bekerja dengan bidang data sebagai gantinya:

import Control.Exception
data D=D()
main=catch @ErrorCall(p$seq(D$error"")0)(\_->p 1);p=print

Mencetak 1dengan flag -XStrictData dan 0dengan -XNoStrictData .

Jika mencetak apa pun dalam satu wadah diperbolehkan, kami dapat menurunkannya hingga 86 byte menggantikan main by (19 byte off oleh dfeuer ):

main=catch @ErrorCall(print$seq(D$error"")0)mempty

Catatan: Semua solusi perlu TypeApplicationsdiatur.


Anda dapat mengurangi ini dengan mudah hingga 98 byte, yang kebetulan cocok dengan solusi saya (sangat berbeda). TIO .
dfeuer

Sebenarnya, Anda bisa melakukan yang lebih baik: alih-alih mencetak dalam handler pengecualian, gunakan saja pure().
dfeuer

1
@ PDFeuer: Bagus, D{}triknya keren! Cukur satu lagi dengan menggunakan PartialTypeSignaturesalih-alih ScopedTypeVariables:)
ბიმო

1
@ PDFeuer: Saya telah melihat dan mencoba beberapa hal, tetapi saya tidak pernah menggunakan Generics, jadi saya mungkin bukan orang yang tepat.
17:58

1
Anda dapat melakukan lebih baik lagi dengan GHC tepi berdarah dan -XBlockArguments:main=catch @ErrorCall(p$seq(D$error"")1)\_->p 3
dfeuer

6

ApplicativeDo, 146 byte

newtype C a=C{u::Int}
instance Functor C where fmap _ _=C 1
instance Applicative C
instance Monad C where _>>=_=C 0
main=print$u$do{_<-C 0;pure 1}

Mencetak 1 saat ApplicativeDo diaktifkan, 0 sebaliknya

Cobalah online!


1
Terima kasih! Ah, saya pikir saya menggunakan GHC versi lama ("no aplikatif" adalah peringatan pada sistem saya)
oisdk

3
Menggunakan -XDeriveAnyClass Anda dapat memperoleh Applicativedan Showmenyimpan menggunakan sintaksis catatan, lihat ini .
ბიმო

6

BinaryLiterals, 31 24 byte

Edit:

  • -7 byte: H.PWiz menyarankan untuk menyesuaikan lebih lanjut dengan menggunakan b12variabel tunggal .

Penyesuaian dengan metode H.PWiz , menghindari instance fungsi.

b12=1
main=print$(+)0b12

6

ExtendedDefaultRules, 54 53 byte

instance Num()
main=print(toEnum 0::Num a=>Enum a=>a)

Mencetak ()dengan -XExtendedDefaultRulesdan0 dengan -XNoExtendedDefaultRules.

Bendera ini diaktifkan secara default di GHCi, tetapi tidak di GHC, yang baru-baru ini menyebabkan kebingungan bagi saya , meskipun BMO dengan cepat dapat membantu.

Kode di atas adalah versi golf dari contoh di Panduan Pengguna GHC di mana jenis default di GHCi dijelaskan.

-1 byte terima kasih kepada Ørjan Johansen !


Sambil melihat kode ini dipinjam ke dalam polyglot (di mana kurung memberikan beberapa masalah), saya ingat bahwa GHC mendukung sintaks satu byte yang lebih pendek toEnum 0::Num a=>Enum a=>a.
Ørjan Johansen

Anda bisa mendapatkannya turun ke 48 byte dengan PartialTypeSignatures: main=print(toEnum 0::_=>Num a=>a). Juga, tautan TIO Anda kedaluwarsa.
dfeuer

6

RebindableSyntax , 25 byte

Saya sedang membaca Panduan untuk Ekstensi GHC yang baru-baru ini diposting ketika saya melihat yang mudah yang saya belum ingat melihat di sini.

main|negate<-id=print$ -1

Juga membutuhkan -XImplicitPrelude, atau sebagai alternatif import Preludedalam kode itu sendiri.

  • -XRebindableSyntax mengubah perilaku beberapa gula sintaksis Haskell untuk memungkinkannya mendefinisikannya kembali.
  • -1adalah gula sintaksis untuk negate 1.
  • Biasanya ini negateadalah Prelude.negate, tapi dengan ekstensi itu "mananegate dalam lingkup pada titik penggunaan", yang didefinisikan sebagai id.
  • Karena ekstensi dimaksudkan untuk digunakan untuk membuat penggantian untuk Preludemodul, ia secara otomatis menonaktifkan impor implisit yang biasa dari itu, tetapi Preludefungsi lain (seperti print) diperlukan di sini, jadi itu diaktifkan kembali dengan -XImplicitPrelude.

6

Ketat, 52 byte

import GHC.IO
f _=print()
main=f$unsafePerformIO$f()

-Ketat

-XNoStrict

Dengan -XStrict , cetakan() waktu ekstra.

Terima kasih kepada @Sriotchilism O'Zaic untuk dua byte.


6

StrictData, 58 bytes

import GHC.Exts
data D=D Int
main=print$unsafeCoerce#D 3+0

(Tautan sedikit ketinggalan zaman; akan diperbaiki.)

-XNoStrictData

-XStrictData

Membutuhkan MagicHash(agar kami mengimpor GHC.Extsbukan Unsafe.Coerce) dan-O (benar-benar diperlukan, untuk mengaktifkan pembongkaran bidang kecil yang ketat).

Dengan -XStrictData, mencetak 3. Jika tidak, mencetak nilai integer dari pointer (mungkin ditandai) ke salinan pra-alokasi3::Integer , yang tidak mungkin 3.

Penjelasan

Ini akan menjadi sedikit lebih mudah untuk dipahami dengan sedikit ekspansi, berdasarkan tipe defaulting. Dengan tanda tangan, kita bisa menjatuhkan tambahan.

main=print
  (unsafeCoerce# D (3::Integer)
    :: Integer)

Setara,

main=print
  (unsafeCoerce# $
    D (unsafeCoerce# (3::Integer))
    :: Integer)

Mengapa cetak 3? Ini sepertinya mengejutkan! Nah, Integernilai-nilai kecil direpresentasikan sangat mirip Ints, yang (dengan data ketat) direpresentasikan seperti ituD s. Kami akhirnya mengabaikan tag yang menunjukkan apakah bilangan bulat kecil atau besar positif / negatif.

Mengapa tidak dapat mencetak 3 tanpa ekstensi? Mengesampingkan alasan tata letak memori, penunjuk data dengan bit rendah (2 terendah untuk 32-bit, 3 terendah untuk 64-bit) dari 3 harus mewakili nilai yang dibangun dari konstruktor ketiga. Dalam hal ini, itu akan membutuhkan bilangan bulat negatif .


5

UnboxedTuples, 52 byte

import Language.Haskell.TH
main=runQ[|(##)|]>>=print

Membutuhkan -XTemplateHaskell. Mencetak ConE GHC.Prim.(##)dengan -XUnboxedTuples dan UnboundVarE ##dengan -XNoUnboxedTuples .


Tidakkah seharusnya ada +16 lainnya dalam skor untuk opsi yang diperlukan -XTemplateHaskell?
celtschk

2
@celtschk Saya tidak menghitungnya karena konsensus meta saat ini pada bendera baris perintah mengatakan mereka tidak dihitung tetapi merupakan bahasa baru sebagai gantinya. Meskipun saat memikirkannya saya melihat bahwa dalam konteks tantangan ini yang hanya memungkinkan jawaban Haskell tetapi juga penggunaan bendera lain, tidak begitu jelas apa yang harus dilakukan. Saya akan bertanya OP tentang hal itu.
Laikoni

Saya tidak sadar bahwa konsensus tentang ini telah berubah. Terima kasih atas penunjuknya. Meminta OP adalah ide yang bagus.
celtschk

5

Daftar Overloaded, 76 byte

import GHC.Exts
instance IsList[()]where fromList=(():)
main=print([]::[()])

Dengan -XOverloadedLists mencetak [()]. Dengan -XNoOverloadedLists mencetak[]

Ini membutuhkan bendera tambahan: -XFlexibleInstances,-XIncoherentInstances


Anda bisa lolos dengan contoh yang tumpang tindih.
dfeuer

5

HexFloatLiterals , 49 25 byte

-24 byte berkat Ørjan Johansen.

main|(.)<-seq=print$0x0.0

Mencetak 0.0dengan -XHexFloatLiteralsdan0 dengan -XNoHexFloatLiterals.

Tidak ada tautan TIO karena HexFloatLiterals ditambahkan dalam ghc 8.4.1, tetapi TIO memiliki ghc 8.2.2.


main|(.)<-seq=print$0x0.0menghindari persembunyian impor.
Ørjan Johansen

main|let _._=0=print$0x0.0mungkin lebih mudah untuk polyglot.
Ørjan Johansen

5

ScopedTypeVariables, 37 byte

main=print(1::_=>a):: a.a~Float=>_

Ini juga memerlukan UnicodeSyntax, PartialTypeSignatures, GADTs, dan ExplicitForAll.

Cobalah online (tanpa ekstensi)

Cobalah online (dengan ekstensi)

Penjelasan

Jenis tanda tangan parsial hanya untuk menyimpan byte. Kita bisa mengisinya seperti ini:

main=print(1::(Num a, Show a)=>a):: a.a~Float=>IO ()

Dengan variabel tipe cakupan, adalam tipe 1dibatasi menjadi atipe main, yang dengan sendirinya dibatasi Float. Tanpa variabel tipe cakupan, 1default untuk mengetik Integer. Sejak FloatdanInteger nilai ditampilkan secara berbeda, kita dapat membedakannya.

Terima kasih kepada @ ØrjanJohansen untuk 19 byte kekalahan! Dia menyadari bahwa itu jauh lebih baik untuk mengambil keuntungan dari perbedaan antara Showcontoh dari tipe numerik yang berbeda daripada perbedaan dalam hitungnya. Dia juga menyadari bahwa tidak apa-apa untuk meninggalkan jenis main"ambigu secara sintaksis" karena kendala sebenarnya merusaknya. Menyingkirkan fungsi lokal juga membebaskan saya untuk menghapus tanda tangan tipe untuk main(menggesernya ke RHS) untuk menghemat lima byte lagi.



@ ØrjanJohansen, bagus .
dfeuer

@ ØrjanJohansen, haruskah saya mengeditnya, atau Anda ingin menambahkan sendiri?
dfeuer

Edit, itu adalah evolusi bertahap dari Anda.
Ørjan Johansen

@ ØrjanJohansen, terima kasih, itu indah.
dfeuer

5

DeriveAnyClass, 121 113 byte

Berkat dfeuer untuk beberapa byte!

import Control.Exception
newtype M=M Int deriving(Show,Num)
main=handle h$print(0::M);h(_::SomeException)=print 1

-XDeriveAnyClass mencetak 1sedangkan -XNoDeriveAnyClass mencetak M 0.

Ini mengeksploitasi fakta bahwa DeriveAnyClass adalah strategi default ketika DeriveAnyClass dan GeneralizedNewtypeDeriving diaktifkan, seperti yang dapat Anda lihat dari peringatan. Bendera ini akan dengan senang hati menghasilkan implementasi kosong untuk semua metode, tetapi GeneralizedNewtypeDeriving sebenarnya cukup pintar untuk menggunakan implementasi tipe yang mendasarinya dan karenaInt merupakan Numtidak akan gagal dalam hal ini.


Jika tidak mencetak apa-apa jika bendera diaktifkan menggantikan mainyang berikut ini akan menjadi 109 byte :

main=print(0::M)`catch`(mempty::SomeException->_)

Setidaknya dalam runhaskell, ini benar-benar dicetak M 1dengan -XDeriveAnyClass, karena kemalasan ...
berhenti mengubah counterclockwis

@ceasedtoturncounterclockwis: Ya di GHCi juga, tetapi ketika mengkompilasi pada TIO (dan mesin saya) & kemudian menjalankannya menghasilkan 1:)
ბიმო



1
Saya turun ke 104 dengan cara yang sama sekali berbeda, jadi saya menambahkan jawaban saya sendiri.
dfeuer

4

PostfixOperators, 63 byte

import Text.Show.Functions
instance Num(a->b)
main=print(0`id`)

Cobalah online (tanpa ekstensi)

Cobalah online (dengan ekstensi)

Ini adalah versi cut-down polyglot Hugs / GHC yang saya tulis . Lihat posting itu untuk penjelasan. Terima kasih kepada @ ØrjanJohansen karena menyadari bahwa saya dapat menggunakan idalih-alih operator kustom, menghemat empat byte.


idbisa digunakan sebagai ganti !.
Ørjan Johansen

@ ØrjanJohansen, ya memang! Itu menghemat empat byte keren.
dfeuer




3

TemplateHaskell, 140 91 byte

Baru saja disalin dari mauke dengan modifikasi kecil. Saya tidak tahu apa yang sedang terjadi.

-49 byte berkat Ørjan Johansen.

import Language.Haskell.TH
instance Show(Q a)where show _=""
main=print$(pure$TupE[]::ExpQ)

Cobalah online!


$(...)(tanpa spasi) adalah sintaks evaluasi templat ketika TH diaktifkan, dan TupE[]("tuple kosong") memberikan (). MenggunakanShow mungkin bekerja dengan baik untuk polyglot, meskipun untuk tantangan khusus ini saya merasa agak buruk tentang mendefinisikan nilai untuk dicetak sebagai string kosong ...
Ørjan Johansen

2

Pembatasan Monomorfisme, 31 29 byte

Edit:

  • -2 byte dengan peningkatan oleh H.PWiz
f=(2^)
main=print$f$f(6::Int)

-XMonomorphismRestriction mencetak 0. -XNoMonomorphismRestriction mencetak 18446744073709551616.

  • Dengan pembatasan, kedua penggunaan fdipaksa untuk menjadi tipe yang sama, sehingga program mencetak 2^2^6 = 2^64sebagai 64-bit Int(pada platform 64-bit), yang meluap ke 0.
  • Tanpa batasan, program mencetak 2^64sebagai bignum Integer.

1
Saya pikir f=(2^);main=print$f$f(64::Int)akan menghemat satu byte. Tapi itu tidak akan berakhir secara realistis
H.PWiz

@ H.PWiz Untungnya 64=2^6, yang menyimpan byte lain.
Ørjan Johansen

1

ScopedTypeVariables, 119 97 byte

Baru saja disalin dari mauke dengan modifikasi kecil.

Saat ini ada dua jawaban lain untuk ScopedTypeVariables: 113 byte oleh Csongor Kiss dan 37 byte oleh dfeuer . Kiriman ini berbeda karena tidak memerlukan ekstensi Haskell lainnya.

-22 byte berkat Ørjan Johansen.

class(Show a,Num a)=>S a where s::a->IO();s _=print$(id::a->a)0
instance S Float
main=s(0::Float)

Cobalah online!


97 byte (walaupun IO()/printtriknya tidak akan bekerja di polyglot).
Ørjan Johansen

@ ØrjanJohansen Saya menambahkan ScopedTypeVariables, tetapi merusak ExtendedDefaultRules . Bagaimana bisa diperbaiki? Saya sudah memiliki kesalahan seperti itu sebelumnya, tetapi saya tidak dapat menerapkan penjelasan Anda di sini. Kode ScopedTypeVariables yang saya tambahkan adalah ini .
stasoid

Begitu ya, kodenya menggunakan trik default yang serupa, dan mereka saling mengganggu. Salah satu solusinya adalah membiarkan yang baru menggunakan kelas yang lebih terbatas daripada Num. Saya pikir class(Show a,Floating a)=>K a where{k::a->String;k=pure$ show(f pi)where f=id::a->a};harus bekerja, mudah menggunakannya Floatdan Doubletampilan pidengan presisi berbeda.
Ørjan Johansen

@ ØrjanJohansen Wow, pas sekali. Terima kasih.
stasoid
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.