So your thoughts on seeing this title might be “Holy cow, an article about imports…could there be anymore more boring?” But bear with me. This is actually something that is to do correctly. But if you’re even a bit lazy (as I often am), you’ll do it wrong. And that can have on you and your teammates’ productivity. pretty easy really bad effects Imagine someone is trying to make their to your codebase. They have which functions are defined where. They aren’t necessarily familiar with the libraries you use. So what happens when they come across a function they don’t know? They’ll search for the definition in the file itself. But if it’s not there, they’ll have to look to the . first contribution no idea imports section Once you’ve built a Haskell program of even modest size, you’ll appreciate the importance of the imports section of any source file. Almost any nontrivial program requires code beyond the base libraries. This means you’ll have to import library code that you got through Stack or Cabal. You’ll also want different parts of your code working together. So naturally your different modules will import each other as well. When you write your imports list properly, your contributors will love you. They’ll know exactly where they need to look to find the right documentation. Write it poorly, and they’ll be stuck and frustrated. They’ll lose all kinds of time googling and hoogling function definitions. Tech stacks like Java and iOS have mature IDEs like IntelliJ or XCode. These make it easy someone to click on a method and find documentation for it. But you can’t count on people having these features for their Haskell environment yet. So now imagine the function or expression they’re looking for is not defined in the file they’re looking at. They’ll need to figure out themselves which module imported it. Here are some good practices to make this an easy process. Only Import the Functions You Need The first way to make your imports clearer is to you import. The biggest temptation is to only write the module name in the import. This will allow you to use any function from that library. But you can also limit the functions you use. You do this with a parenthesized list after the module name. specify which functions import Data.List.Split (splitOn) import Data.Maybe (isJust, isNothing) Now suppose someone sees the splitOn function in your code and doesn’t know what it does, or what its type is. By looking at your imports list, they know they can find out by googling the Data.List.Split library. Qualifying Imports The second way to clarify your imports is to use the keyword. This means that you must prefix every function you use from this module by a name assigned to the module. You can either use the full module name, or you can use use the keyword. This indicates you will refer to the module by a different, generally shorter name. qualified as import qualified Data.Map as Mimport qualified Data.List.Split...myMap :: M.Map String [String]myMap = M.fromList [(“first”, Data.List.Split.splitOn “abababababa” “a”)] In this example, a contributor can see exactly where our functions and types came from. The function and the “Map” data structure belong to the module, thanks to the “M” prefix. The function also clearly comes from . fromList Data.Map splitOn Data.List.Split You can even import the . This allows you to namespace certain functions in different ways. This helps to avoid prefixing type names, so your type signatures remain clean. In this example, we explicitly import the type from . Then we also make it a qualified import, allowing us to use other functions like . same module in different ways ByteString Data.ByteString empty import qualified Data.ByteString as Bimport Data.ByteString (ByteString)…myByteString :: ByteStringmyByteString = B.empty Organizing Your Imports Next, you should separate the internal imports from the external ones. That is, you should have two lists. The first list consists of built-in packages. The second list has modules that are in the codebase itself. In this example, the “OWA” modules are from within the codebase. The other modules are either Haskell base libraries or downloaded from Hackage: import qualified Data.List as Limport System.IO (openFile)import qualified Text.PrettyPrint.Leijen as PPrint import OWAPrintUtilimport OWASwiftAbSyn This is important because it tells someone . If it’s from the first list, they will immediately know whether they need to look online. For imports on the second list, they can find the file within the codebase. where to look for the modules You can provide more help by name-spacing your module names. For instance, you can attach your project name (or an abbreviation) to the front of all your modules’ names, as above. An even better approach is to separate your modules by folder and have period spacing. This makes it more clear where to look within the file structure of the codebase for it. Organizing your code cleanly in the first place can also help this process. For instance, it might be a good idea to have one module that contains all the types for a particular section of the codebase. Then it should be obvious to users where the different type names are coming from. This can save you from needing to qualify all your type names, or have a huge list of types imported from a module. Making the List Easy to Read On a final note, you want to your import list. If you have a single qualified import in a list, line up all the other imports with it. This means spacing them out as if they also used the word . This makes it so the actual names of the modules all line up. make it easy to read qualified Next, write your list in alphabetical order. This helps people find the right module in the list. Finally, also try to line up the statements and specific function imports as best you can. This way, it’s easy for people to see what different module prefixes you're using. This is another feature you can get from Haskell text editor plugins. as import qualified Data.ByteString (ByteString)import qualified Data.Map as Mimport Data.Maybe as May Summary Organizing your imports is key to making your code accessible to others developers! Make it clear where functions come from by. You can do this in two ways. You can either qualify your imports or specify which functions you use from a module. Separate library imports from your own code imports. This let’s people know if they need to look online or in the codebase for the module. Make the imports list itself easy to read by alphabetizing it and lining all the names up. Stay tuned for next week! We’ll take a tour through all the different string types in Haskell! This is another topic that ought to be simple but has many pitfalls, especially for beginners! We’ll focus on the different ways to convert between them. If you’ve never a line of Haskell before don’t despair! You can check out our . It will walk you through downloading Haskell and point you in the direction of some good learning resources. Getting Started Checklist If you’ve done a little bit of Haskell before but want some practice on the fundamentals, you should take a look at our . It has two chapters of content followed by 10 practice problems for you to look at! Recursion Workbook is how hackers start their afternoons. We’re a part of the family. We are now and happy to opportunities. Hacker Noon @AMI accepting submissions discuss advertising & sponsorship To learn more, , , or simply, read our about page like/message us on Facebook tweet/DM @HackerNoon. If you enjoyed this story, we recommend reading our and . Until next time, don’t take the realities of the world for granted! latest tech stories trending tech stories