Đợi đã, đây là ngôn ngữ gì?


37

Gần đây tôi rất vui khi viết một chương trình Haskell có thể phát hiện nếu NegativeLiteralsphần mở rộng được tham gia. Tôi đã đưa ra những điều sau đây:

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

Hãy thử trực tuyến!

Điều này sẽ in Truebình thường và Falsekhác.

Bây giờ tôi đã có rất nhiều niềm vui khi làm điều này Tôi đang mở rộng thử thách cho tất cả các bạn. Những phần mở rộng ngôn ngữ Haskell khác bạn có thể crack?

Quy tắc

Để bẻ khóa một phần mở rộng ngôn ngữ cụ thể, bạn phải viết chương trình Haskell biên dịch cả có và không có phần mở rộng ngôn ngữ (cảnh báo là tốt) và đưa ra hai giá trị không lỗi khác nhau khi chạy với phần mở rộng ngôn ngữ và nó tắt (bằng cách thêm Notiền tố vào phần mở rộng ngôn ngữ). Theo cách này, đoạn mã trên có thể được rút ngắn thành:

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

mà in 1-1.

Bất kỳ phương pháp nào bạn sử dụng để bẻ khóa một phần mở rộng phải cụ thể cho phần mở rộng đó. Có thể có các cách tự ý phát hiện cờ nào của trình biên dịch hoặc LanguageExtensions được bật, nếu vậy các phương thức đó không được phép. Bạn có thể kích hoạt các phần mở rộng ngôn ngữ bổ sung hoặc thay đổi tối ưu hóa trình biên dịch bằng cách sử dụng -Omiễn phí cho số byte của bạn.

Phần mở rộng ngôn ngữ

Bạn không thể crack bất kỳ phần mở rộng ngôn ngữ mà không có một Nođối tác (ví dụ Haskell98, Haskell2010, Unsafe, Trustworthy, Safe) vì những không thuộc các điều khoản nêu trên. Mỗi phần mở rộng ngôn ngữ khác là trò chơi công bằng.

Chấm điểm

Bạn sẽ được thưởng một điểm cho mỗi tiện ích mở rộng ngôn ngữ mà bạn là người đầu tiên bẻ khóa và một điểm bổ sung cho mỗi tiện ích mở rộng ngôn ngữ mà bạn có vết nứt ngắn nhất (tính bằng byte). Đối với các mối quan hệ điểm thứ hai sẽ được phá vỡ để ủng hộ đệ trình trước đó. Điểm cao hơn là tốt hơn

Bạn sẽ không thể ghi điểm cho lần gửi đầu tiên NegativeLiteralshoặc QuasiQuotesvì tôi đã bẻ khóa chúng và đưa chúng vào phần thân bài. Tuy nhiên, bạn sẽ có thể ghi một điểm cho vết nứt ngắn nhất trong số này. Đây là vết nứt của tôiQuasiQuotes

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

Hãy thử trực tuyến!


3
Tôi nghĩ rằng đây là danh sách tất cả các tùy chọn hợp lệ
H.PWiz

1
Lưu ý rằng nhận xét trên của tôi không bao gồm NondecreasingIndentationvì những lý do rõ ràng
H.PWiz

4
Tôi nghĩ tiêu đề này là sai lệch, vì ngôn ngữ duy nhất bạn có thể sử dụng là Haskell. Làm thế nào về Wait, what language extension is this?Hoặc một cái gì đó hoàn toàn khác nhau.
MD XF

1
Tôi khá tò mò liệu có thể bẻ khóa được không RelaxedPolyRec, vì một trình biên dịch đủ cổ xưa để thực sự hỗ trợ tắt nó đi. (Tùy chọn treo xung quanh, với tài liệu, trong một vài năm sau khi nó ngừng làm bất cứ điều gì.)
dfeuer

1
@dfeuer Nhìn vào này, có vẻ như GHC 6.12.1 đã hỗ trợ tắt nó đi.
Ørjan Johansen

Câu trả lời:


24

MagicHash, 30 byte

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

-XMagicHash xuất ra 1, -XNoMagicHash xuất 2

MagicHash cho phép các tên biến chấm dứt trong a #. Do đó, với phần mở rộng, điều này xác định hai hàm y#x#mỗi hàm lấy một giá trị và trả về một hằng 2, hoặc 1. x#xsẽ trả về 1 (vì nó được x#áp dụng cho 1)

Không có phần mở rộng, điều này xác định một hàm #có hai đối số và trả về 2. Đây x#a=1là một mô hình không bao giờ đạt được. Sau đó x#x1#1, mà trả về 2.


2
Bây giờ tôi đang hát X Magic Hash theo giai điệu của Dance Magic Dance . Tôi hy vọng bạn tự hào!
TRiG

Tôi ngạc nhiên rằng MagicHashkhông cho phép băm không dấu vết. Kỳ dị!
dfeuer

18

CPP, 33 20 byte

main=print$0-- \
 +1

In 0với -XCPP1với -XNoCPP.

Với -XCPP, một dấu gạch chéo \trước khi một dòng mới xóa dòng mới, do đó mã trở thành main=print$0-- +1và chỉ 0được in như +1bây giờ là một phần của nhận xét.

Không có cờ, bình luận sẽ bị bỏ qua và dòng thứ hai được phân tích cú pháp như là một phần của dòng trước đó vì nó được thụt lề.


Cách tiếp cận trước với #define

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

Cũng in 0với -XCPP1với -XNoCPP.


2
Trời ơi, cho đến bây giờ tôi nghĩ GHC sẽ loại bỏ các bình luận của Haskell trước khi chuyển qua CPP.
Khối

@Cubic Nó không phải là tiền xử lý?
Bergi

1
@Bergi Chắc chắn, nhưng các bộ tiền xử lý không nhất thiết có nghĩa là "là thứ đầu tiên chạy", đặc biệt là khi GHC phải vượt qua tệp trước để thậm chí tìm thấy pragma. Tôi đoán ý kiến ​​được lưu giữ để bình luận doc và công việc tương tự sau khi CPP được thực hiện.
Khối


14

Nhị phân, 57 byte

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

-XBinaryLiterals in một dòng mới. -XNoBinaryLiterals in a 1.

Tôi chắc chắn có một cách tốt hơn để làm điều này. Nếu bạn tìm thấy một, xin vui lòng gửi nó.


Bạn không thể chỉ định nghĩa blà một hàm (vì vậy không có nhị phân nào trở thành b(0, 1), nhưng nhị phân trở thành 0b1)?
NoOneIsHãy

12

MonomorphismRestriction + 7 khác, 107 byte

Điều này sử dụng TH yêu cầu cờ -XTemplateHaskellmọi lúc.

Tệp T.hs, 81 + 4 byte

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

Chính, 22 byte

import T
main=print $t

Biên dịch với cờ MonomorphismRestriction buộc loại pđến Integer -> Integer -> Integervà do đó tạo ra đầu ra sau:

"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"

Biên dịch với cờ NoMonomorphismRestriction để lại kiểu ptổng quát nhất, nghĩa là. Num a => a->a->a- sản xuất một cái gì đó như (rút ngắn VarTtên thành 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"

Hãy thử chúng trực tuyến!


Lựa chọn thay thế

Vì đoạn mã trên chỉ đơn giản là in ra loại p, nên điều này có thể được thực hiện với tất cả các cờ ảnh hưởng đến cách thức Haskell nhập vào các loại. Tôi sẽ chỉ xác định cờ và với những gì cần thay thế chức năng pvà nếu cần thêm cờ (bên cạnh -XTemplateHaskell):

Quá tảiLists, 106 byte

Ngoài ra cần -XNoMonomorphismRestriction:

p=[]

Hoặc là p :: [a]hay p :: IsList l => l, thử chúng trực tuyến!

OverloadedStrings, 106 byte

Ngoài ra cần -XNoMonomorphismRestriction:

p=""

Hoặc là p :: Stringhay p :: IsString s => s, thử chúng trực tuyến!

PolyKinds, 112 byte

Điều này hoàn toàn do @CsongorKiss:

data P a=P 

Hoặc là P :: P ahay P :: forall k (a :: k). P a, thử chúng trực tuyến!

MonadCompTHERensions, 114 byte

p x=[i|i<-x]

Hoặc là p :: [a] -> [a]hay p :: Monad m => m a -> m a, thử chúng trực tuyến!

NamedWildCards, 114 byte

Cái này được tìm thấy bởi @Laikoni, nó cũng yêu cầu -XPartialTypeSignatures:

p=id::_a->_a

Cả hai đều có kiểu lưu ( p :: a -> a) nhưng GHC tạo các tên khác nhau cho các biến, hãy thử trực tuyến!

ApplicativeDo, 120 byte

p x=do i<-x;pure i

Hoặc là p :: Monad m => m a -> m ahay p :: Functor f => f a -> f a, thử chúng trực tuyến!

Quá tảiLabels, 120 byte

Điều này cần cờ bổ sung -XFlexibleContexts:

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

Hoặc là loại p :: a -> b -> bhoặc p :: IsLabel "id" (a->b) => a -> b, hãy thử chúng trực tuyến!


Liệu một điều tương tự làm việc cho các cờ khác?
H.PWiz

Vâng, bạn có thể làm điều đó với OverloadedStringshoặc OverloadedListscho chắc chắn và có lẽ những người khác cũng ..
ბიმო

2
Nó cũng hoạt động với PolyKinds: Hãy thử trực tuyến!
Csongor Kiss

1
Cũng có vẻ để làm việc với NamedWildCards: Hãy thử trực tuyến! (Yêu cầu -XPartialTypeSignatures)
Laikoni

10

CPP, 27 25

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

Hãy thử trực tuyến!

In ()cho -XCPP1cho-XNoCPP

Phiên bản trước:

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

Hãy thử trực tuyến!

In [1]với -XCPP[1,2]nếu không.

Tín dụng: Điều này được lấy cảm hứng từ câu trả lời của Laikoni, nhưng thay vì #definenó chỉ sử dụng các bình luận C.


9

ScopedTypeVariabled, 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()

-XScopedTypeVariabled in ""(trống), -XNoScopedTypeVariabled in "[()]".

Chỉnh sửa: giải pháp cập nhật nhờ các đề xuất hữu ích trong các ý kiến


1
Ah tôi thấy. Nó thường đẹp hơn để bao gồm mã của bạn trong cơ thể, nhưng các phiên bản không có bản quyền cũng tốt. Tôi cũng nhận thấy rằng "T"chỉ có thể được thay thế bằng "".
Thuật sĩ lúa mì

2
Một điều khác bạn có thể làm là thay thế kiểu dữ liệu của bạn Tbằng (). Để tránh phải xác định nó. Hãy thử trực tuyến!
Thuật sĩ lúa mì

1
Bắt tốt, tôi chỉ nhận ra rằng pragma không liên tục có thể được bao gồm như một lá cờ: Hãy thử trực tuyến!
Csongor Kiss

2
Ngoài ra show có thể thay đổi để in
H.PWiz

Cú pháp Unicode cho forallsẽ giúp bạn tiết kiệm một vài byte. Tôi nghi ngờ bất kỳ giải pháp nào cần thêm trường hợp có nhiều hy vọng chiến thắng, mặc dù.
dfeuer

9

MonoLocalBinds, GADTs hoặc TypeFamflower, 36 32 byte

CHỈNH SỬA:

  • -4 byte: Một phiên bản này đã được tích hợp vào chuỗi polyglot tuyệt vời bởi stasoid, người đã làm tôi ngạc nhiên khi đặt tất cả các khai báo ở mức cao nhất. Rõ ràng kích hoạt hạn chế này không yêu cầu ràng buộc địa phương thực tế .
a=0
f b=b^a
main=print(f pi,f 0)
  • Không có phần mở rộng , chương trình này in (1.0,1).
  • Với một trong các cờ -XMonoLocalBinds , -XGADTs hoặc -XTypeFamflower , nó sẽ in (1.0,1.0).

  • Phần MonoLocalBindsmở rộng tồn tại để ngăn chặn một số suy luận kiểu không trực quan được kích hoạt bởi GADT và các họ kiểu. Như vậy, phần mở rộng này được tự động bật bởi hai cái khác.

  • thể tắt nó đi một lần nữa một cách rõ ràng với -XNoMonoLocalBinds, thủ thuật này giả định bạn không.
  • Giống như nó anh em họ nổi tiếng hơn những hạn chế monomorphism, MonoLocalBindshoạt động bằng cách ngăn chặn một số giá trị ( trong cam kết ràng buộc địa phương như lethoặc where, đúng như tên gọi dường như nó cũng có thể xảy ra ở cấp cao nhất) từ việc đa hình. Mặc dù được tạo ra cho suy luận kiểu saner, các quy tắc khi nó kích hoạt là nếu có thể thậm chí nhiều lông hơn MR.

  • Không có bất kỳ tiện ích mở rộng nào, chương trình trên sẽ nhập loại f :: Num a => a -> a, cho phép f pimặc định thành a Doublef 0thành một Integer.

  • Với các phần mở rộng, loại suy ra trở thành f :: Double -> Double, và f 0đã trở lại một Doublelà tốt.
  • Biến riêng biệt a=0là cần thiết để kích hoạt các quy tắc kỹ thuật: ađược ảnh hưởng bởi hạn chế monomorphism, và alà một biến miễn phí của f, có nghĩa là fnhóm ràng buộc 's không khái quát hóa hoàn toàn , mà có nghĩa là fkhông được đóng lại và do đó không trở thành đa hình.

9

OverloadedStrings, 65 48 32 byte

Tận dụng lợi thế của RebindableSyntax, hãy sử dụng phiên bản fromString của riêng chúng tôi để biến bất kỳ chuỗi ký tự nào thành "y".

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

Phải được biên dịch với -XRebindableSyntax -XImplicitPrelude.

Không có -XOverloadedStringsbản in ""; có in hình "y".

Ngoài ra, điều này chỉ cho tôi thấy rằng kỹ thuật tương tự hoạt động với (ví dụ) OverloadedLists:

Quá tảiLists, 27 byte

main=print[0]
fromListN=(:)

Phải được biên dịch với -XRebindableSyntax -XImplicitPrelude.

Không có -XOverloadedListsbản in [0]; có in hình [1,0].


1
Bạn có thể rút ngắn dòng cuối cùng để fromString a=['y'].
Ørjan Johansen

Không gian trong print "n"cũng có thể được thả.
Laikoni

@ ØrjanJohansen cảm ơn! Tôi đã có nó thất bại với ="y", nhưng =['y']hoạt động tốt!
felixphew

1
Bạn có thể xóa cái thứ hai nkhỏiprint"n"
Wheat Wizard

1
Bạn cũng có thể sử dụng -XImplicitPreludesau RebindableSyntaxđể tránh dòng nhập khẩu.
dfeuer

8

BangPotypes, 32 byte

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

-XBangPotypes in 1trong khi -XNoBangPotypes sẽ in 0.

Điều này làm cho việc sử dụng cờ BangPotype cho phép chú thích các mẫu với một !đánh giá để buộc đánh giá vào WHNF, trong trường hợp đó 9!1sẽ sử dụng định nghĩa cấp cao nhất (!)=seq. Nếu cờ không được bật, hãy f!_xác định toán tử mới (!)và đổ bóng cho định nghĩa cấp cao nhất.


7

ApplicativeDo, 104 byte

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

Hãy thử trực tuyến!

Với ApplicativeDo, bản in này

ZipList {getZipList = [1]}

Không có nó, nó in

ZipList {getZipList = []}

ZipListlà một trong số ít các loại trong các thư viện cơ sở với một thể hiện cho Applicativenhưng không phải cho Monad. Có thể có những lựa chọn thay thế ngắn hơn ẩn nấp ở đâu đó.


7

Nghiêm, 87 84 82 byte

-5 byte nhờ dfeuer !

Có thể ít hơn với việc BlockArgumentslưu các parens xung quanh \_->print 1:

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

Chạy cái này với -XStrict in một cái 1trong khi chạy nó với -XNoStrict sẽ in một 0. Điều này sử dụng Haskell theo mặc định là lười biếng và không cần đánh giá error""vì nó đã biết rằng kết quả sẽ xảy ra 0khi nó khớp với đối số đầu tiên (!), hành vi này có thể được thay đổi với cờ đó - buộc thời gian chạy phải đánh giá cả hai đối số.

Nếu việc in không có gì trong một trường hợp được cho phép, chúng tôi có thể giảm xuống còn 75 byte thay thế chính bằng (cũng có một số byte bị tắt bởi dfeuer ):

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

StrictData, 106 99 93 byte

-15 byte nhờ vào dfeuer !

Điều này về cơ bản làm tương tự nhưng hoạt động với các trường dữ liệu thay thế:

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

In 1bằng cờ -XStrictData0với -XNoStrictData .

Nếu in không có gì trong một trường hợp được cho phép, chúng tôi có thể giảm xuống còn 86 byte thay thế chính bằng (tắt 19 byte bởi dfeuer ):

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

Lưu ý: Tất cả các giải pháp yêu cầu TypeApplicationsthiết lập.


Bạn có thể cắt nó xuống khá dễ dàng đến 98 byte, điều này xảy ra khớp chính xác với giải pháp (rất khác biệt) của tôi. TIO .
dfeuer

Trên thực tế, bạn có thể làm tốt hơn nữa: thay vì in trong trình xử lý ngoại lệ, chỉ cần sử dụng pure().
dfeuer

1
@dfeuer: Hay đấy, D{}mẹo khá hay đấy! Cạo nhau tắt bằng cách sử dụng PartialTypeSignaturesthay vì ScopedTypeVariables:)
ბიმო

1
@dfeuer: Tôi đã xem và thử một vài thứ, nhưng tôi chưa bao giờ sử dụng Generics, vì vậy tôi có lẽ không phải là người phù hợp.
ბიმო

1
Bạn có thể làm tốt hơn nữa với GHC chảy máu và -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}

In 1 khi ApplicativeDo được bật, 0 nếu không

Hãy thử trực tuyến!


1
Cảm ơn! À, tôi nghĩ rằng tôi đang dùng phiên bản GHC cũ hơn ("không áp dụng" là một cảnh báo trên hệ thống của tôi)
oonomk

3
Sử dụng -XDeriveAnyClass bạn có thể rút ra ApplicativeShowđể lưu bằng cú pháp bản ghi, xem phần này .
ბიმო


6

ExtendedDefaultRules, 54 53 byte

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

In ()với -XExtendedDefaultRules0với -XNoExtendedDefaultRules.

Cờ này được bật theo mặc định trong GHCi, nhưng không phải trong GHC, gần đây đã gây ra một số nhầm lẫn cho tôi , mặc dù BMO đã nhanh chóng có thể giúp đỡ.

Đoạn mã trên là phiên bản được đánh gôn của một ví dụ trong Hướng dẫn sử dụng GHC nơi giải thích mặc định kiểu trong GHCi .

-1 byte nhờ rjan Johansen !


Trong khi xem mã này được mượn vào polyglot (trong đó dấu ngoặc đơn gây ra một số rắc rối), tôi nhớ rằng GHC hỗ trợ cú pháp ngắn hơn một byte toEnum 0::Num a=>Enum a=>a.
Ørjan Johansen

Bạn có thể giảm xuống còn 48 byte với PartialTypeSignatures: main=print(toEnum 0::_=>Num a=>a). Ngoài ra, liên kết TIO của bạn đã hết hạn.
dfeuer

6

RebindableSyntax , 25 byte

Tôi đang đọc Hướng dẫn được đăng gần đây về Tiện ích mở rộng của GHC khi tôi nhận thấy một cách dễ dàng mà tôi chưa nhớ là đã thấy ở đây.

main|negate<-id=print$ -1

Cũng yêu cầu -XImplicitPrelude, hoặc thay thế import Preludetrong chính mã.

  • -XRebindableSyntax thay đổi hành vi của một số đường cú pháp của Haskell để có thể xác định lại nó.
  • -1là cú pháp đường cho negate 1.
  • Thông thường, đây negatePrelude.negate, nhưng với phần mở rộng, "bất kỳ negatephạm vi nào tại điểm sử dụng", được định nghĩa là id.
  • Vì tiện ích mở rộng được sử dụng để thay thế cho Preludemô-đun, nên nó tự động vô hiệu hóa việc nhập ngầm định thông thường của nó, nhưng các Preludechức năng khác (như print) là cần thiết ở đây, do đó, nó được kích hoạt lại -XImplicitPrelude.


6

StrictData, 58 byte

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

(Liên kết hơi lỗi thời; sẽ sửa.)

-XKhôngStrictData

-XStrictData

Yêu cầu MagicHash(để chúng tôi nhập GHC.Extsthay vì Unsafe.Coerce) và -O(hoàn toàn bắt buộc, để cho phép giải nén các trường nghiêm ngặt nhỏ).

Với -XStrictData, in 3. Mặt khác, in giá trị nguyên của con trỏ (có thể được gắn thẻ) sang bản sao được phân bổ trước 3::Integer, có thể không thể là 3.

Giải trình

Sẽ dễ hiểu hơn một chút với một chút mở rộng, dựa trên kiểu mặc định. Với chữ ký, chúng tôi có thể bỏ bổ sung.

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

Tương đương,

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

Tại sao nó bao giờ in 3? Điều này có vẻ đáng ngạc nhiên! Chà, các Integergiá trị nhỏ được biểu diễn rất giống Ints, mà (với dữ liệu nghiêm ngặt) được biểu diễn giống như Ds. Chúng tôi cuối cùng bỏ qua thẻ cho biết số nguyên là nhỏ hay lớn dương / âm.

Tại sao nó không thể in 3 mà không có phần mở rộng? Bỏ qua mọi lý do bố trí bộ nhớ, một con trỏ dữ liệu có bit thấp (2 thấp nhất cho 32 bit, 3 thấp nhất cho 64 bit) phải biểu thị một giá trị được xây dựng từ hàm tạo thứ ba. Trong trường hợp này, điều đó sẽ yêu cầu một số nguyên âm .


5

UnboxedTuples, 52 byte

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

Yêu cầu -XTemplateHaskell. In ConE GHC.Prim.(##)với -XUnboxedTuplesUnboundVarE ##với -XNoUnboxedTuples .


Không nên có thêm +16 điểm cho tùy chọn bắt buộc -XTemplateHaskell?
celtschk

2
@celtschk Tôi không tính nó vì sự đồng thuận meta hiện tại về cờ dòng lệnh nói rằng chúng không được tính mà thay vào đó là một ngôn ngữ mới. Mặc dù suy nghĩ về nó, tôi thấy rằng trong bối cảnh của thử thách này chỉ cho phép câu trả lời của Haskell nhưng việc sử dụng các cờ khác thì không rõ phải làm gì. Tôi sẽ hỏi OP về nó.
Laikoni

Tôi đã không biết rằng sự đồng thuận về điều này đã thay đổi. Cảm ơn bạn cho con trỏ. Hỏi OP là một ý tưởng tốt cho chắc chắn.
celtschk

5

Quá tảiLists, 76 byte

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

Với -XOverloadedLists nó in [()]. Với -XNoOverloadedLists nó in[]

Điều này đòi hỏi các cờ bổ sung : -XFlexibleInstances,-XIncoherentInstances


Bạn có thể thoát khỏi các trường hợp chồng chéo.
dfeuer

5

HexFloatLiterals , 49 25 byte

-24 byte nhờ Ørjan Johansen.

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

In 0.0với -XHexFloatLiterals0với -XNoHexFloatLiterals.

Không có liên kết TIO vì HexFloatLiterals đã được thêm vào ghc 8.4.1, nhưng TIO có ghc 8.2.2.


main|(.)<-seq=print$0x0.0tránh việc ẩn nhập.
Ørjan Johansen

main|let _._=0=print$0x0.0có thể dễ dàng hơn cho polyglot mặc dù.
Ørjan Johansen

5

ScopedTypeVariabled, 37 byte

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

Điều này cũng đòi hỏi UnicodeSyntax, PartialTypeSignatures, GADTs, và ExplicitForAll.

Dùng thử trực tuyến (không có phần mở rộng)

Dùng thử trực tuyến (có phần mở rộng)

Giải trình

Chữ ký loại một phần chỉ để lưu byte. Chúng ta có thể điền chúng vào như vậy:

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

Với các biến loại có phạm vi, akiểu trong 1bị ràng buộc là akiểu trong mainđó, chính nó bị hạn chế Float. Không có biến loại phạm vi, 1mặc định để gõ Integer. Vì FloatIntegercác giá trị được hiển thị khác nhau, chúng ta có thể phân biệt chúng.

Cảm ơn @ rjanJohansen vì đã thu được 19 byte! Ông nhận ra rằng sẽ tốt hơn nhiều nếu tận dụng sự khác biệt giữa các Showtrường hợp của các loại số khác nhau hơn là sự khác biệt về số học của chúng. Ông cũng nhận ra rằng không sao khi để loại main"mơ hồ về mặt cú pháp" bởi vì các ràng buộc thực sự làm cho nó không rõ ràng. Việc loại bỏ chức năng cục bộ cũng giải phóng tôi để xóa chữ ký loại cho main(chuyển nó sang RHS) để lưu thêm năm byte.



@ RjanJohansen, tốt đẹp .
dfeuer

@ RjanJohansen, tôi nên chỉnh sửa, hoặc bạn muốn thêm cái riêng của mình?
dfeuer

Chỉnh sửa, đó là một sự tiến hóa dần dần từ bạn.
Ørjan Johansen

@ RjanJohansen, cảm ơn, thật là đẹp.
dfeuer

5

DeriveAnyClass, 121 113 byte

Cảm ơn dfeuer cho khá nhiều byte!

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

-XDeriveAnyClass in 1trong khi -XNoDeriveAnyClass in M 0.

Điều này đang khai thác thực tế rằng DeriveAnyClass là chiến lược mặc định khi cả DeriveAnyClass và GeneralizedNewtypeDeriving đều được bật, như bạn có thể thấy từ các cảnh báo. Cờ này hạnh phúc sẽ tạo triển khai sản phẩm nào cho tất cả các phương pháp nhưng GeneralizedNewtypeDeriving thực sự là đủ thông minh để sử dụng thực hiện các loại hình cơ bản và kể từ khi Intlà một Numnó sẽ không thất bại trong trường hợp này.


Nếu in không có gì trong trường hợp cờ được bật thay thế mainbằng cách sau đây sẽ là 109 byte :

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

Ít nhất là trong runhaskell, điều này thực sự in M 1với -XDeriveAnyClass, vì sự lười biếng ...
đã ngừng quay ngược lại vào

@ceasedtoturncounterclockwis: Yes trong GHCi là tốt, nhưng khi biên dịch trên TIO (và máy tính của tôi) & sau đó chạy nó kết quả trong 1:)
ბიმო



1
Tôi đã hạ nó xuống 104 theo một cách hoàn toàn khác, vì vậy tôi đã thêm câu trả lời của riêng mình.
dfeuer

4

PostfixOperators, 63 byte

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

Dùng thử trực tuyến (không có phần mở rộng)

Dùng thử trực tuyến (có phần mở rộng)

Đây là phiên bản rút gọn của một polyglot Hugs / GHC tôi đã viết . Xem bài đăng đó để giải thích. Cảm ơn @ rjanJohansen vì đã nhận ra tôi có thể sử dụng idthay vì một toán tử tùy chỉnh, tiết kiệm bốn byte.


idcó thể được sử dụng thay thế !.
Ørjan Johansen

@ RjanJohansen, đúng vậy! Điều đó tiết kiệm bốn byte mát mẻ.
dfeuer




3

TemplateHaskell, 140 91 byte

Chỉ cần sao chép từ mauke với sửa đổi nhỏ. Tôi không biết chuyện gì đang xảy ra.

-49 byte nhờ rjan Johansen.

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

Hãy thử trực tuyến!


$(...)(không có khoảng TupE[]trắng ) là cú pháp đánh giá mẫu khi TH được bật và ("tuple trống") đưa ra (). Việc sử dụngShow có thể hoạt động tốt cho polyglot, mặc dù đối với thử thách cụ thể này, tôi cảm thấy hơi tệ khi xác định giá trị để in dưới dạng một chuỗi trống ...
Ørjan Johansen

2

Đơn hình biến đổi, 31 29 byte

Chỉnh sửa:

  • -2 byte với sự cải tiến của H.PWiz
f=(2^)
main=print$f$f(6::Int)

-XMonomorphismRestriction in 0. -XNoMonomorphismRestriction in 18446744073709551616.

  • Với các hạn chế, hai cách sử dụng fbị buộc phải cùng loại, do đó chương trình in 2^2^6 = 2^64dưới dạng 64 bit Int(trên nền tảng 64 bit), tràn ra 0.
  • Không có giới hạn, chương trình in 2^64dưới dạng một bignum Integer.

1
Tôi nghĩ rằng f=(2^);main=print$f$f(64::Int)sẽ tiết kiệm một byte. Nhưng nó sẽ không thực sự chấm dứt
H.PWiz

@ H.PWiz May mắn thay 64=2^6, nó tiết kiệm được một byte khác.
Ørjan Johansen

1

ScopedTypeVariabled, 119 97 byte

Chỉ cần sao chép từ mauke với sửa đổi nhỏ.

Hiện tại có hai câu trả lời khác cho ScopedTypeVariabled: 113 byte của Csongor Kiss37 byte của dfeuer . Trình này khác ở chỗ nó không yêu cầu các phần mở rộng Haskell khác.

-22 byte nhờ Ø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)

Hãy thử trực tuyến!


97 byte (mặc dù IO()/printthủ thuật sẽ không hoạt động trong polyglot).
Ørjan Johansen

@ RjanJohansen Tôi đã thêm ScopedTypeVariabled, nhưng đã phá vỡ ExtendedDefaultRules . Làm thế nào nó có thể được sửa chữa? Tôi đã có lỗi như vậy trước đây, nhưng tôi không thể áp dụng lời giải thích của bạn ở đây. Mã ScopedTypeVariabled tôi đã thêm là đây .
stasoid

Tôi thấy, các mã sử dụng các thủ thuật mặc định tương tự và chúng giao thoa với nhau. Một giải pháp là để cho cái mới sử dụng một lớp hạn chế hơn Num. Tôi nghĩ class(Show a,Floating a)=>K a where{k::a->String;k=pure$ show(f pi)where f=id::a->a};nên làm việc, thuận tiện sử dụng FloatDoublehiển thị pivới độ chính xác khác nhau.
Ørjan Johansen

@ RjanJohansen Wow, nó phù hợp ngay. Cảm ơn bạn.
stasoid
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.